ฉันจะรู้ได้อย่างไรว่าคอมไพเลอร์ทำลายรหัสของฉันและฉันจะทำอย่างไรถ้ามันเป็นคอมไพเลอร์?


14

ในบางครั้งรหัส C ++ จะไม่ทำงานเมื่อรวบรวมกับการเพิ่มประสิทธิภาพในระดับหนึ่ง มันอาจเป็นการคอมไพเลอร์ที่ทำการปรับให้เหมาะสมที่ทำลายรหัสหรืออาจเป็นรหัสที่มีพฤติกรรมที่ไม่ได้กำหนดซึ่งช่วยให้คอมไพเลอร์ทำสิ่งที่รู้สึก

สมมติว่าฉันมีโค้ดบางส่วนที่หยุดพักเมื่อคอมไพล์ด้วยระดับการเพิ่มประสิทธิภาพที่สูงขึ้นเท่านั้น ฉันจะรู้ได้อย่างไรว่ามันเป็นรหัสหรือคอมไพเลอร์และฉันจะทำอย่างไรถ้ามันเป็นคอมไพเลอร์?


43
น่าจะเป็นคุณ
littleadv

9
@littleadv แม้ gcc และ msvc เวอร์ชันล่าสุดจะเต็มไปด้วยข้อบกพร่องดังนั้นฉันจึงไม่แน่ใจ
SK-logic

3
คุณเปิดใช้งานคำเตือนทั้งหมดหรือไม่

@ Thorbjørn Ravn Andersen: ใช่ฉันเปิดใช้งานแล้ว
sharptooth

3
FWIW: 1) ฉันพยายามที่จะไม่ทำสิ่งใดที่ซับซ้อนที่อาจจะทำให้คอมไพเลอร์เลอะเทอะ 2) จุดเดียวที่การตั้งค่าสถานะการปรับให้เหมาะสมนั้นสำคัญที่สุด (สำหรับความเร็ว) อยู่ในโค้ดที่ตัวนับโปรแกรมใช้เวลาอย่างมีนัยสำคัญ นอกจากว่าคุณกำลังเขียน cpu ลูปแน่น ๆ ในหลาย ๆ แอปพลิเคชั่นพีซีใช้เวลาส่วนใหญ่ในห้องสมุดหรือใน I / O ในแอพประเภทนั้นสวิตช์ / O ไม่ได้ช่วยอะไรคุณเลย
Mike Dunlavey

คำตอบ:


19

ฉันจะบอกว่ามันเป็นเดิมพันที่ปลอดภัยที่ในกรณีส่วนใหญ่มันเป็นรหัสของคุณไม่ใช่คอมไพเลอร์ที่เสีย และแม้ในกรณีพิเศษเมื่อเป็นคอมไพเลอร์คุณอาจใช้ภาษาที่ไม่ชัดเจนในลักษณะที่ผิดปกติซึ่งคอมไพเลอร์เฉพาะไม่ได้เตรียมไว้ กล่าวอีกนัยหนึ่งคุณอาจเปลี่ยนรหัสของคุณให้เป็นสำนวนที่มากขึ้นและหลีกเลี่ยงจุดอ่อนของคอมไพเลอร์

ถ้าคุณสามารถพิสูจน์ได้ว่าคุณพบข้อผิดพลาดของคอมไพเลอร์ (ขึ้นอยู่กับสเป็คภาษา) รายงานผู้พัฒนาคอมไพเลอร์เพื่อให้พวกเขาอาจได้รับการแก้ไขในบางเวลา


@ SK-ตรรกะยุติธรรมพอฉันไม่มีสถิติที่จะสำรอง มันขึ้นอยู่กับประสบการณ์ของตัวเองและฉันยอมรับว่าฉันไม่ค่อยได้ จำกัด ขอบเขตของภาษาและ / หรือคอมไพเลอร์ - คนอื่น ๆ อาจทำบ่อยขึ้น
PéterTörök

(1) @ SK-Logic: เพิ่งพบข้อผิดพลาดของคอมไพเลอร์ C ++, รหัสเดียวกัน, ลองใช้กับคอมไพเลอร์ตัวหนึ่งและใช้งานได้
umlcat

8
@umlcat: เป็นไปได้ว่ารหัสของคุณขึ้นอยู่กับพฤติกรรมที่ไม่ได้ระบุ ในคอมไพเลอร์ตัวหนึ่งมันตรงกับความคาดหวังของคุณ นั่นไม่ได้หมายความว่ามันจะพัง
Javier

@ Ritch Melton คุณเคยใช้ LTO ไหม?
SK-logic

1
ฉันเห็นด้วยกับ Crashworks เมื่อพูดถึงคอนโซลเกม ไม่ใช่เรื่องแปลกเลยที่จะพบข้อผิดพลาดของคอมไพเลอร์ลึกลับในสถานการณ์เฉพาะนั้น หากคุณกำลังกำหนดเป้าหมายพีซีปกติโดยใช้คอมไพเลอร์ที่ใช้งานหนักมันไม่น่าเป็นไปได้มากที่คุณจะชนกับคอมไพเลอร์บั๊กที่ไม่มีใครเคยเห็นมาก่อน
Trevor Powell

14

เช่นเดียวกับข้อบกพร่องอื่น ๆ : ทำการทดสอบที่ควบคุม จำกัด ขอบเขตที่น่าสงสัยให้แคบลงปิดการปรับให้เหมาะสมสำหรับทุกอย่างและเริ่มปรับการปรับให้เหมาะสมกับโค้ดอันนั้น เมื่อคุณได้รับความสามารถในการทำซ้ำได้ 100% ให้เริ่มเปลี่ยนรหัสของคุณแนะนำสิ่งต่าง ๆ ที่อาจทำให้การเพิ่มประสิทธิภาพบางอย่างไม่เหมาะสม (เช่นแนะนำให้ใช้นามแฝงตัวชี้ที่เป็นไปได้แทรกการโทรภายนอกด้วยผลข้างเคียงที่อาจเกิดขึ้น ฯลฯ ) การดูรหัสประกอบในตัวดีบักอาจช่วยได้เช่นกัน


อาจช่วยอะไร ถ้าเป็นบั๊กคอมไพเลอร์ - แล้วไงล่ะ
littleadv

2
@littleadv หากเป็นข้อผิดพลาดของคอมไพเลอร์คุณสามารถลองแก้ไขได้ (หรือเพียงแค่รายงานอย่างถูกต้องโดยละเอียด) หรือคุณสามารถหาวิธีหลีกเลี่ยงได้ในอนาคตหากคุณยังคงใช้มันต่อไป เวอร์ชั่นของคอมไพเลอร์ของคุณสักพัก หากเป็นสิ่งที่มีรหัสของคุณเองซึ่งเป็นหนึ่งในปัญหาเส้นขอบ C ++ - ish มากมายการตรวจสอบประเภทนี้จะช่วยในการแก้ไขข้อบกพร่องและหลีกเลี่ยงปัญหาดังกล่าวในอนาคต
SK-logic

ดังที่ฉันได้กล่าวไว้ในคำตอบของฉัน - นอกเหนือจากการรายงานแล้วมันไม่มีความแตกต่างในการรักษามากนัก
littleadv

3
@littleadv โดยไม่เข้าใจลักษณะของปัญหาคุณอาจต้องเผชิญกับปัญหาซ้ำแล้วซ้ำอีก และมักจะมีความเป็นไปได้ในการแก้ไขคอมไพเลอร์ด้วยตัวเอง และใช่มันไม่ใช่ "ไม่น่าเป็นไปได้เลยที่จะหาบั๊กในคอมไพเลอร์ C ++ แต่น่าเสียดายที่
SK-logic

10

ตรวจสอบรหัสแอสเซมบลีที่เกิดขึ้นและดูว่ามันทำในสิ่งที่มาของคุณเรียก โปรดจำไว้ว่าอัตราเดิมพันนั้นสูงมากซึ่งเป็นรหัสของคุณที่ผิดปกติในบางรูปแบบที่ไม่ชัดเจน


1
นี่เป็นคำตอบเดียวสำหรับคำถามนี้ งานคอมไพเลอร์ในกรณีนี้คือการนำคุณจาก C ++ ไปยังภาษาแอสเซมบลี คุณคิดว่ามันเป็นคอมไพเลอร์ ... ตรวจสอบคอมไพเลอร์ทำงาน มันง่ายมาก
old_timer

7

ในช่วงเวลา 30 ปีของการเขียนโปรแกรมจำนวนข้อผิดพลาดของคอมไพเลอร์ (การสร้างรหัส) ที่ฉันได้พบนั้นยังคงมีเพียง ~ 10 จำนวนข้อบกพร่องของฉัน (และคนอื่น ๆ ) ที่ฉันพบและแก้ไขในช่วงเวลาเดียวกัน > 10,000 "กฎของหัวแม่มือ" ของฉันนั้นคือความน่าจะเป็นของข้อผิดพลาดใด ๆ ที่เป็นเพราะคอมไพเลอร์คือ <0.001


1
คุณโชคดี. ค่าเฉลี่ยของฉันประมาณ 1 ข้อผิดพลาดที่เลวร้ายจริงๆต่อเดือนและปัญหาเส้นขอบเล็กน้อยเป็นวิธีที่บ่อยกว่ามาก และเมื่อระดับการปรับให้เหมาะสมสูงสุดที่คุณใช้อยู่สูงกว่าโอกาสเกิดข้อผิดพลาดของคอมไพเลอร์ หากคุณพยายามใช้ -O3 และ LTO คุณจะโชคดีมากที่ไม่พบพวกเขาสองสามคนในเวลาไม่นาน และฉันนับเฉพาะข้อบกพร่องในรุ่นที่วางจำหน่าย - ในฐานะนักพัฒนาคอมไพเลอร์ฉันกำลังเผชิญกับปัญหามากกว่านั้นในงานของฉัน แต่ก็ไม่นับ ฉันเพิ่งรู้ว่ามันง่ายแค่ไหนที่จะไขลานคอมไพเลอร์
SK-logic

2
25 ปีและฉันก็เคยเห็นมาแล้วมากมาย คอมไพเลอร์เริ่มแย่ลงทุกปี
old_timer

5

ฉันเริ่มเขียนความคิดเห็นจากนั้นจึงตัดสินใจนานเกินไปและตรงประเด็นมากเกินไป

ฉันจะยืนยันว่ามันเป็นรหัสของคุณที่เสีย ในเหตุการณ์ที่ไม่น่าเป็นไปได้ที่คุณค้นพบข้อบกพร่องในคอมไพเลอร์ - คุณควรรายงานไปยังผู้พัฒนาคอมไพเลอร์ แต่นั่นคือสิ่งที่ความแตกต่างสิ้นสุดลง

วิธีแก้ปัญหาคือการระบุโครงสร้างที่สร้างความขุ่นเคืองและปรับโครงสร้างใหม่เพื่อที่จะทำตรรกะเดียวกันต่างกัน นั่นน่าจะแก้ปัญหาได้ไม่ว่าข้อผิดพลาดจะอยู่ข้างคุณหรือในคอมไพเลอร์


5
  1. อ่านรหัสของคุณอีกครั้ง ตรวจสอบให้แน่ใจว่าคุณไม่ได้ทำสิ่งใดที่มีผลข้างเคียงใน ASSERT หรือคำสั่งเฉพาะอื่น ๆ ในการดีบัก (หรือมากกว่านั้นโดยทั่วไป) ยังจำได้ว่าในการแก้ปัญหาสร้างหน่วยความจำที่ได้รับการเริ่มต้นที่แตกต่างกัน - ค่าตัวชี้ปากโป้งคุณสามารถตรวจสอบได้ที่นี่: การแก้จุดบกพร่อง - การรับรองจัดสรรหน่วยความจำ เมื่อเรียกใช้จากภายใน Visual Studio คุณเกือบจะใช้ Debug Heap (แม้ในโหมดรีลีส) เว้นแต่คุณจะระบุด้วยตัวแปรสภาพแวดล้อมอย่างชัดเจนว่านี่ไม่ใช่สิ่งที่คุณต้องการ
  2. ตรวจสอบงานสร้างของคุณ เป็นเรื่องปกติที่จะเกิดปัญหากับการสร้างที่ซับซ้อนในสถานที่อื่นนอกเหนือจากคอมไพเลอร์จริง - การพึ่งพามักจะเป็นผู้กระทำผิด ฉันรู้ว่า "คุณได้ลองสร้างใหม่ทั้งหมด" เกือบจะเป็นคำตอบที่ทำให้โกรธเป็น "คุณได้ลองติดตั้ง windows ใหม่" แต่ก็มักจะช่วย ลอง: ก) การรีบูตเครื่อง b) การลบไฟล์กลางและไฟล์เอาท์พุตทั้งหมดของคุณด้วยตนเองและสร้างใหม่
  3. ดูรหัสของคุณเพื่อตรวจสอบตำแหน่งที่อาจเกิดขึ้นซึ่งคุณอาจเรียกใช้พฤติกรรมที่ไม่ได้กำหนด หากคุณทำงานใน C ++ มาสักพักคุณจะรู้ว่ามีบางจุดที่คุณคิดว่า "ฉันไม่แน่ใจว่าฉันได้รับอนุญาตให้สมมติ ... " - google หรือถามที่นี่เกี่ยวกับเรื่องนั้น ประเภทของรหัสเพื่อดูว่ามันเป็นพฤติกรรมที่ไม่ได้กำหนดหรือไม่
  4. หากยังไม่เป็นเช่นนั้นให้สร้างเอาต์พุตที่ประมวลผลล่วงหน้าสำหรับไฟล์ที่ทำให้เกิดปัญหา การขยายตัวของแมโครที่ไม่คาดคิดสามารถทำให้เกิดความสนุกได้ทุกประเภท (ฉันนึกถึงเวลาที่เพื่อนร่วมงานตัดสินใจว่าแมโครด้วยชื่อของ H จะเป็นความคิดที่ดี ... ) ตรวจสอบเอาต์พุตที่ประมวลผลล่วงหน้าสำหรับการเปลี่ยนแปลงที่ไม่คาดคิดระหว่างการกำหนดค่าโครงการของคุณ
  5. ทางเลือกสุดท้าย - ตอนนี้คุณอยู่ในคอมไพล์บั๊กคอมไพล์แล้ว - ดูผลลัพธ์ของแอสเซมบลี นี่อาจใช้การขุดและการต่อสู้เพื่อให้ได้รับการจัดการกับสิ่งที่แอสเซมบลีกำลังทำอยู่ แต่จริง ๆ แล้วเป็นข้อมูลค่อนข้างมาก คุณสามารถใช้ทักษะที่คุณเลือกได้ที่นี่เพื่อประเมินการเพิ่มประสิทธิภาพขนาดเล็กเช่นกันดังนั้นทั้งหมดจะไม่สูญหายไป

+1 สำหรับ "พฤติกรรมที่ไม่ได้กำหนด" ฉันถูกกัดโดยคนนั้น เขียนโค้ดบางอย่างที่ขึ้นอยู่กับint + intการโอเวอร์โฟลว์เหมือนกับว่ามันได้ทำการคอมไพล์ลงในคำสั่ง ADD ของฮาร์ดแวร์ มันใช้งานได้ดีเมื่อคอมไพล์ด้วย GCC เวอร์ชันเก่า แต่ไม่ใช่เมื่อคอมไพล์ด้วยคอมไพเลอร์ใหม่กว่า เห็นได้ชัดว่าคนดีที่ GCC ตัดสินใจว่าเนื่องจากผลของการล้นจำนวนเต็มไม่ได้กำหนดเครื่องมือเพิ่มประสิทธิภาพของพวกเขาสามารถทำงานภายใต้สมมติฐานที่ว่ามันไม่เคยเกิดขึ้น มันปรับสาขาที่สำคัญออกจากรหัส
โซโลมอนช้า

2

ถ้าคุณต้องการทราบว่ามันเป็นรหัสหรือคอมไพเลอร์ของคุณคุณต้องรู้สเปคของ C ++ อย่างสมบูรณ์

หากยังมีข้อสงสัยอยู่คุณจะต้องรู้ชุด x86 อย่างสมบูรณ์

หากคุณไม่ได้อยู่ในอารมณ์ของการเรียนรู้ทั้งสองอย่างเพื่อความสมบูรณ์แบบมันเป็นพฤติกรรมที่ไม่ได้กำหนดไว้อย่างแน่นอนซึ่งคอมไพเลอร์ของคุณจะแก้ไขแตกต่างกันไปตามระดับการปรับให้เหมาะสม


(+1) @mouviciel: มันยังขึ้นอยู่กับว่าฟีเจอร์นั้นรองรับโดยคอมไพเลอร์แม้ว่าจะอยู่ในสเปค ฉันมีข้อผิดพลาดแปลก ๆ กับ gcc ฉันประกาศ "โครงสร้าง c ธรรมดา" ด้วย "ตัวชี้ฟังก์ชั่น" ซึ่งได้รับอนุญาตในสเปค แต่ทำงานในบางสถานการณ์และไม่ได้อยู่ในอีก
umlcat

1

การรับข้อผิดพลาดในการคอมไพล์ในรหัสมาตรฐานหรือข้อผิดพลาดในการคอมไพล์ภายในมีแนวโน้มมากกว่าตัวเพิ่มประสิทธิภาพที่ผิด แต่ฉันเคยได้ยินว่าคอมไพเลอร์ปรับลูปอย่างไม่ถูกต้องให้ลืมวิธีที่ทำให้เกิดผลข้างเคียง

ฉันไม่มีข้อเสนอแนะเกี่ยวกับวิธีการที่จะรู้ว่าคุณหรือคอมไพเลอร์ คุณอาจลองคอมไพเลอร์อื่น

อยู่มาวันหนึ่งฉันสงสัยว่ามันเป็นรหัสของฉันหรือไม่และมีคนแนะนำ valgrind ให้ฉัน ฉันใช้เวลา 5 หรือ 10 นาทีในการรันโปรแกรมด้วย (ฉันคิดว่าvalgrind --leak-check=yes myprog arg1 arg2ทำ แต่ฉันเล่นกับตัวเลือกอื่น ๆ ) และมันแสดงให้ฉันเห็นหนึ่งบรรทัดที่วิ่งภายใต้กรณีเฉพาะซึ่งเป็นปัญหา จากนั้นแอพของฉันก็ทำงานได้อย่างราบรื่นนับตั้งแต่ที่ไม่มีข้อผิดพลาดแปลก ๆ ข้อผิดพลาดหรือพฤติกรรมแปลก ๆ valgrind หรือเครื่องมืออื่นเช่นมันเป็นวิธีที่ดีที่จะรู้ว่ารหัสของคุณ

หมายเหตุด้านข้าง: ฉันเคยสงสัยว่าทำไมประสิทธิภาพของแอปของฉันถึงถูกดูด มันกลับกลายเป็นว่าปัญหาการปฏิบัติงานของฉันทั้งหมดอยู่ในบรรทัดเดียวเช่นกัน for(int i=0; i<strlen(sz); ++i) {ที่ผมเขียน sz คือไม่กี่ mb ด้วยเหตุผลบางอย่างคอมไพเลอร์รัน strlen ทุกครั้งแม้หลังจากการปรับให้เหมาะสม บรรทัดเดียวอาจเป็นเรื่องใหญ่ ตั้งแต่การแสดงจนล่ม


1

สถานการณ์ที่พบบ่อยมากขึ้นคือคอมไพเลอร์รหัสผิดพลาดที่เขียนขึ้นสำหรับภาษาถิ่นของ C ที่สนับสนุนพฤติกรรมที่ไม่ได้รับคำสั่งจากมาตรฐานและอนุญาตให้ใช้รหัสที่กำหนดเป้าหมายภาษาเหล่านั้นให้มีประสิทธิภาพมากกว่ารหัสที่สอดคล้องกันอย่างเคร่งครัด ในกรณีเช่นนี้มันจะไม่ยุติธรรมที่จะอธิบายว่าเป็นรหัส "เสีย" ซึ่งจะเชื่อถือได้ 100% ในคอมไพเลอร์ที่ใช้ภาษาเป้าหมายหรือเพื่ออธิบายว่า "แตก" คอมไพเลอร์ซึ่งประมวลผลภาษาที่ไม่สนับสนุนความหมายที่ต้องการ . แต่ปัญหาเกิดขึ้นจากความจริงที่ว่าภาษาที่ประมวลผลโดยคอมไพเลอร์สมัยใหม่ที่เปิดใช้งานการปรับให้เหมาะสมนั้นแตกต่างจากภาษาถิ่นที่เคยเป็นที่นิยม (และยังคงถูกประมวลผลโดยคอมไพเลอร์จำนวนมากที่ปิดการใช้งาน

ตัวอย่างเช่นรหัสจำนวนมากถูกเขียนขึ้นสำหรับภาษาถิ่นที่รับรู้ว่ารูปแบบนามแฝงของตัวชี้จำนวนที่ถูกต้องตามกฎหมายไม่ได้รับคำสั่งจากการตีความมาตรฐาน gcc และใช้รูปแบบดังกล่าวเพื่อให้การแปลรหัสตรงไปตรงมาอ่านง่ายและมีประสิทธิภาพมากขึ้น กว่าจะเป็นไปได้ภายใต้การตีความ gcc ของมาตรฐาน C รหัสดังกล่าวอาจเข้ากันไม่ได้กับ gcc แต่นั่นไม่ได้หมายความว่ามันเสีย มันขึ้นอยู่กับส่วนขยายที่ gcc สนับสนุนเท่านั้นเมื่อปิดการใช้งานการเพิ่มประสิทธิภาพ


แน่นอนว่าไม่มีอะไรผิดปกติกับการเข้ารหัสส่วนขยาย X + มาตรฐาน C + Y และ Z ตราบใดที่ให้ข้อดีที่สำคัญกับคุณคุณรู้ว่าคุณทำอย่างนั้นและบันทึกไว้อย่างละเอียด น่าเสียดายที่เงื่อนไขทั้งสามนั้นไม่เป็นไปตามปกติดังนั้นจึงเป็นเรื่องที่เหมาะสมที่จะกล่าวว่ารหัสนั้นใช้งานไม่ได้
Deduplicator

@Dupuplicator: คอมไพเลอร์ C89 ได้รับการเลื่อนตำแหน่งให้เข้ากันได้ดีกับรุ่นก่อนและในทำนองเดียวกันกับ C99 เป็นต้นขณะที่ C89 ไม่มีข้อกำหนดเกี่ยวกับพฤติกรรมที่เคยกำหนดไว้ในบางแพลตฟอร์ม แต่ไม่ใช่สำหรับคนอื่น ๆ แพลตฟอร์มที่ถือว่าพฤติกรรมตามที่กำหนดควรดำเนินการต่อไป เหตุผลในการส่งเสริมประเภทสั้น ๆ ที่ไม่ได้ลงชื่อกับสัญญาณจะแนะนำว่าผู้เขียนคอมไพเลอร์มาตรฐานที่คาดหวังจะประพฤติตนในลักษณะนั้นไม่ว่ามาตรฐานนั้นจะได้รับคำสั่งหรือไม่ก็ตาม เพิ่มเติม ...
supercat

... การตีความอย่างเข้มงวดของกฎนามแฝงจะทำให้ความเข้ากันได้ของหน้าต่างสูงขึ้นและทำให้รหัสไม่สามารถใช้งานได้หลายอย่าง แต่มีการปรับแต่งเล็กน้อยเล็กน้อย (เช่นการระบุรูปแบบบางอย่างที่ควรคาดหวังนามแฝงไขว้แบบข้ามและอนุญาต) . วัตถุประสงค์ทั้งหมดของกฎดังกล่าวคือเพื่อหลีกเลี่ยงการกำหนดให้คอมไพเลอร์ทำ "นามแฝง" ในนามสมมุติฐาน แต่ได้รับ "โฟลต x" ควรสันนิษฐานว่า "foo ((int *) & x)" อาจแก้ไข x แม้ว่า "foo" doesn ไม่เขียนถึงตัวชี้ประเภทใด ๆ 'float * "หรือ" char * "ถูกพิจารณาว่าเป็น" มองโลกในแง่ร้าย "หรือ" ชัดเจน "?
supercat

0

แยกจุดที่มีปัญหาและเปรียบเทียบพฤติกรรมที่สังเกตได้กับสิ่งที่ควรเกิดขึ้นตามข้อมูลจำเพาะภาษา ไม่ใช่เรื่องง่ายแน่นอน แต่นั่นคือสิ่งที่คุณต้องทำเพื่อรู้ (และไม่เพียงแค่คิด )

ฉันอาจจะไม่พิถีพิถัน แต่ฉันจะขอรายชื่อฟอรัมสนับสนุน / รายชื่อผู้รับจดหมายของคอมไพเลอร์ หากเป็นข้อบกพร่องในคอมไพเลอร์จริงๆพวกเขาอาจแก้ไขได้ อาจจะเป็นรหัสของฉันต่อไป ตัวอย่างเช่นรายละเอียดทางภาษาเกี่ยวกับการมองเห็นหน่วยความจำในเธรดนั้นค่อนข้างใช้งานง่ายและพวกเขาอาจปรากฏได้ก็ต่อเมื่อใช้การตั้งค่าสถานะการปรับแต่งเฉพาะบางอย่างบนฮาร์ดแวร์บางตัว (!) พฤติกรรมบางอย่างอาจไม่ได้ถูกกำหนดโดยสเป็คดังนั้นจึงสามารถทำงานกับคอมไพเลอร์ / แฟล็กบางอย่างและไม่สามารถทำงานร่วมกับคนอื่น ๆ ได้ ฯลฯ


0

รหัสของคุณส่วนใหญ่มีพฤติกรรมที่ไม่ได้กำหนด (ตามที่คนอื่นอธิบายคุณมีแนวโน้มที่จะมีข้อบกพร่องในรหัสของคุณมากกว่าในคอมไพเลอร์แม้ว่าคอมไพเลอร์ C ++ จะซับซ้อนมากจนพวกเขามีข้อบกพร่องก็ตาม . และ UB สามารถอยู่ที่นี่ได้แม้ว่าการปฏิบัติการที่คอมไพล์จะเกิดขึ้นกับการทำงาน (โดยโชคร้าย)

ดังนั้นคุณควรอ่านบล็อก Lattner ' สิ่งที่โปรแกรมเมอร์ C ทุกคนควรรู้เกี่ยวกับพฤติกรรมที่ไม่ได้กำหนด (ส่วนใหญ่จะใช้กับ C ++ 11 ด้วย)

valgrindเครื่องมือและล่าสุด-fsanitize= ตัวเลือกเครื่องมือที่จะGCC (หรือเสียงดังกราว / LLVM ) ยังเป็นที่ควรจะเป็นประโยชน์ และแน่นอนเปิดใช้งานคำเตือนทั้งหมด:g++ -Wall -Wextra

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.