ทำไมมีคอมไพเลอร์ C น้อยมาก?


72

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

แล้วคอมไพเลอร์ทั้งหมดอยู่ที่ไหน?

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

Scheme และ Forth - ภาษาขนาดเล็กอื่น ๆ ที่แฟน ๆ ชื่นชอบ - อาจมีคอมไพเลอร์มากกว่าผู้ใช้จริง แม้บางอย่างเช่นSMLมี "ร้ายแรง" การใช้งานให้เลือกระหว่างกว่าองศาเซลเซียสในขณะที่การประกาศของคอมไพเลอร์ใหม่ (ยังไม่เสร็จ) C เล็งไปที่การตรวจสอบจริงเห็นตอบสนองเชิงลบบางสวยและการใช้งานที่มีประสบการณ์ต่อสู้เพื่อให้ได้ร่วมสมทบมากพอที่จะได้จับได้ถึง C99

ทำไม? การติดตั้ง C ยากไหม ไม่ใช่ C ++ ผู้ใช้มีความคิดที่บิดเบือนไปมากเกี่ยวกับกลุ่มความซับซ้อนที่อยู่ในนั้นหรือไม่ (เช่นที่จริงแล้วใกล้กับ C ++ มากกว่าโครงการ)


61
MSVC ยังคงนับเป็นคอมไพเลอร์ C89 เป็นอย่างน้อย น่าจะเป็นที่นิยมมากกว่า Intel แม้แต่
Rufflewind

22
Wikipediaมีคอมไพเลอร์ C ค่อนข้างน้อย พวกมันจะพบได้บ่อยมากเมื่อคุณพบว่าตัวเองอยู่ในขอบเขตที่ฝังตัว

113
คุณต้องรวบรวมคอมไพล์เลอร์จำนวนเท่าใดสำหรับการคอมไพล์ C ของคุณ?
ไบรอันเฉิน

76
คำถามขึ้นอยู่กับหลักฐานที่ผิด Analog Devices, armcc, คอมไพเลอร์ C ของ Bruce, Bare-C Cross Compiler, คอมไพเลอร์ Borland, คอมไพเลอร์ clang, คอมไพเลอร์ Cosmic C, คอมไพเลอร์ CodeWarrior, คอมไพเลอร์ dokto, คอมไพเลอร์อีริคสัน, และฉันไม่ได้ออกจาก ตัวอักษรห้าตัวแรกของตัวอักษรยัง มีคอมไพเลอร์ C จำนวนมากอย่างเมามัน คำถามคือ "ทำไมมีคอมไพเลอร์ C น้อยมากถ้าเราไม่นับหลายสิบเหล่านี้เป็นคอมไพเลอร์ C จริง?" คุณได้นิยามคอมไพล์เลอร์ C ส่วนใหญ่ว่าไม่น่าสนใจซึ่งเป็นเหตุผลว่าทำไมมันถึงมีคอมไพล์ไม่มาก
Eric Lippert

19
คำถาม "ทำไม" เป็นคำถามที่ไม่ดีสำหรับเว็บไซต์นี้ในช่วงเวลาที่ดีที่สุดและ "ทำไมไม่" คำถามนั้นแย่กว่า ถ้าฉันได้พบคุณในงานปาร์ตี้และถามว่า "เป็นเช่นนั้นทำไมคุณไม่แข่งเรือใบ?" ฉันคิดว่าคุณถูกต้องแล้วพบว่ามันเป็นคำถามแปลก ๆ คุณไม่จำเป็นต้องให้เหตุผลสำหรับการไม่เข้าร่วมในงานอดิเรกที่ยากลำบากทางเทคนิคมีความเสี่ยงทางร่างกายและมีราคาแพงมาก การเขียนซอฟต์แวร์ที่ไม่มีความสำคัญมีราคาแพงยากและมีความเสี่ยงดังนั้นจึงต้องใช้แรงกระตุ้นมหาศาล คำถามที่ดีกว่าคือ "ทำไมจึงมีคอมไพเลอร์ C จำนวนมาก" มันน่าแปลกใจที่มีมากกว่าหนึ่ง
Eric Lippert

คำตอบ:


153

วันนี้คุณต้องการคอมไพเลอร์ C ตัวจริงเพื่อให้ได้ประสิทธิภาพสูงสุดโดยเฉพาะอย่างยิ่งเนื่องจากภาษาซีไม่ได้อยู่ใกล้กับฮาร์ดแวร์อีกต่อไปเพราะโปรเซสเซอร์ปัจจุบันมีความซับซ้อนอย่างเหลือเชื่อ ( นอกลำดับ , pipelined , superscalar , แคชที่ซับซ้อน& TLB , ดังนั้นต้องมีการจัดตารางการเรียนการสอนฯลฯ ... ) โปรเซสเซอร์ x86 ในปัจจุบันไม่เหมือนกับโปรเซสเซอร์ i386 ของศตวรรษก่อนแม้ว่าทั้งคู่จะสามารถเรียกใช้รหัสเครื่องเดียวกันได้ ดูว่าC ไม่ใช่ภาษาระดับต่ำ (คอมพิวเตอร์ของคุณไม่ใช่กระดาษเร็ว PDP-11)โดย David Chisnall

มีคนไม่กี่คนที่ใช้คอมไพเลอร์ C ที่ไร้เดียงสาที่ไร้ประสิทธิภาพเช่นtinyccหรือnwccเนื่องจากพวกเขาสร้างโค้ดที่ช้ากว่าการเพิ่มประสิทธิภาพคอมไพเลอร์หลายเท่า

การเข้ารหัสคอมไพเลอร์การเพิ่มประสิทธิภาพเป็นเรื่องยาก โปรดสังเกตว่าทั้ง GCC และ Clang กำลังปรับการแสดงรหัส "เป็นกลางภาษาเป็นกลาง" บางส่วน (Gimple สำหรับ GCC, LLVM สำหรับ Clang) ความซับซ้อนของคอมไพเลอร์ C ที่ดีไม่ได้อยู่ในขั้นตอนการแยกวิเคราะห์!

โดยเฉพาะอย่างยิ่งการสร้างคอมไพเลอร์ C ++ นั้นไม่ใช่เรื่องยากกว่าการสร้างคอมไพเลอร์ C: การแยก C ++ และการแปลงให้เป็นรหัสภายในบางตัวนั้นมีความซับซ้อน (เนื่องจากข้อกำหนดของ C ++ นั้นซับซ้อน) แต่เข้าใจกันดีกว่า ซับซ้อน (ภายใน GCC: การเพิ่มประสิทธิภาพระดับกลาง, ภาษาต้นทางและเป้าหมายตัวประมวลผลที่เป็นกลาง, รวบรวมคอมไพเลอร์ส่วนใหญ่, ส่วนที่เหลือมีความสมดุลระหว่าง Front-End สำหรับหลายภาษาและแบ็คเอนด์สำหรับโปรเซสเซอร์หลายตัว) ดังนั้นการเพิ่มประสิทธิภาพคอมไพเลอร์ C ส่วนใหญ่ก็สามารถรวบรวมภาษาอื่น ๆ เช่น C ++, Fortran, D, ... ส่วน C ++ เฉพาะของ GCC อยู่ที่ประมาณ 20% ของคอมไพเลอร์ ...

ยิ่งไปกว่านั้น C (หรือ C ++) ใช้กันอย่างแพร่หลายจนผู้คนคาดหวังว่าโค้ดของพวกเขาจะคอมไพล์ได้แม้ว่ามันจะไม่เป็นไปตามมาตรฐานอย่างเป็นทางการซึ่งไม่ได้กำหนดความหมายที่ชัดเจนของภาษา ของมัน) ดูยังเข้าไปในCompCertพิสูจน์แล้วว่าคอมไพเลอร์ C และม่า-Cวิเคราะห์แบบคงที่ซึ่งดูแลเกี่ยวกับทางการมากขึ้นความหมายของซี

และการปรับให้เหมาะสมนั้นเป็นปรากฏการณ์หางยาว : การใช้การปรับให้เรียบง่ายเพียงไม่กี่อย่างนั้นง่าย แต่ก็ไม่ทำให้คอมไพเลอร์แข่งขันได้! คุณต้องใช้การเพิ่มประสิทธิภาพที่แตกต่างกันจำนวนมากและเพื่อจัดระเบียบและรวมเข้าด้วยกันอย่างชาญฉลาดเพื่อรับคอมไพเลอร์ในโลกแห่งความจริงที่มีการแข่งขัน กล่าวอีกนัยหนึ่งคอมไพเลอร์การปรับให้เหมาะสมที่สุดในโลกแห่งความเป็นจริงต้องเป็นซอฟต์แวร์ที่ซับซ้อน BTW ทั้ง GCC และ Clang / LLVM มีเครื่องกำเนิดรหัส C / C ++ เฉพาะหลาย ๆ เครื่อง และทั้งคู่เป็นสัตว์ขนาดใหญ่ (ซอร์สโค้ดหลายล้านเส้นมีอัตราการเติบโตหลายเปอร์เซ็นต์ในแต่ละปี) กับชุมชนนักพัฒนาขนาดใหญ่ (ไม่กี่ร้อยคนทำงานเต็มเวลาส่วนใหญ่หรืออย่างน้อยครึ่งเวลา)

ขอให้สังเกตว่าไม่มี (ที่ดีที่สุดของความรู้ของฉัน) คอมไพเลอร์ C แบบมัลติเธรดแม้ว่าบางส่วนของคอมไพเลอร์สามารถทำงานแบบขนาน (เช่นการเพิ่มประสิทธิภาพภายในโพรซีเดอร์การเพิ่มประสิทธิภาพการลงทะเบียน และการสร้างแบบขนานด้วยmake -jก็ไม่เพียงพอ (โดยเฉพาะกับLTO )

นอกจากนี้มันเป็นเรื่องยากที่จะได้รับเงินทุนในการเข้ารหัสคอมไพเลอร์ C ตั้งแต่เริ่มต้นและความพยายามดังกล่าวต้องใช้เวลาหลายปีที่ผ่านมา ในที่สุดคอมไพเลอร์ C หรือ C ++ ส่วนใหญ่เป็นซอฟต์แวร์เสรีวันนี้ (ไม่มีตลาดสำหรับคอมไพเลอร์กรรมสิทธิ์ใหม่ที่ขายโดย startups) หรืออย่างน้อยก็เป็นสินค้าผูกขาด (เช่นMicrosoft Visual C ++ ) และการเป็นซอฟต์แวร์ฟรีเกือบเป็นสิ่งจำเป็นสำหรับคอมไพเลอร์ เพราะพวกเขาต้องการความช่วยเหลือจากองค์กรต่าง ๆ มากมาย)

ฉันยินดีที่จะได้รับเงินทุนสำหรับการทำงานกับคอมไพเลอร์ C ตั้งแต่เริ่มต้นเป็นซอฟต์แวร์เสรี แต่ฉันไม่ไร้เดียงสาพอที่จะเชื่อว่าเป็นไปได้ในวันนี้!


14
(there is no more a market for proprietary compilersบอกได้ว่าทีม Visual Studio ...
เมสันล้อ

18
Microsoft มีการผูกขาด ฉันหมายถึงว่า บริษัท ขนาดเล็กที่กำลังพัฒนาคอมไพเลอร์ C ตัวใหม่จะไม่ขายพวกเขาจำนวนมาก คุณสามารถตั้งชื่อคู่แข่งที่เป็นกรรมสิทธิ์ล่าสุดให้กับ MSVC ได้หรือไม่?
Basile Starynkevitch

12
มีคอมไพเลอร์ที่เป็นกรรมสิทธิ์มากมายในโลก HPC PGCC, NAG และ ICC ใช้กันอย่างแพร่หลาย
Davidmh

37
@MasonWheeler: VS แจกฟรีในทุกวันนี้ (เหมือนในเบียร์) รุ่นที่ไม่ใช่ฟรีเพิ่มเครื่องมือ แต่คอมไพเลอร์ C ใน VS2013 เหมือนกันในทุกรุ่น ไม่ใช่แค่ตลาดไม่ใช่สำหรับพวกเขา
MSalters

3
แต่ GCC และ LLVM ทั้งสองทำงานโดยมีค่าใช้จ่ายที่ต่ำกว่ามากและจะเพิ่มประสิทธิภาพของรหัส C ++ & C (& Ada & Fortran สำหรับ GCC) เช่นเดียวกัน ในทางตรงกันข้ามฉันจะบอกว่า C ++ ต้องการการเพิ่มประสิทธิภาพมากขึ้น (โดยเฉพาะอย่างยิ่งเมื่อรวบรวมรหัสโดยใช้ STL) กว่า C!
Basile Starynkevitch

70

ฉันต้องการโต้แย้งสมมติฐานที่คุณมีอยู่ว่ามีการใช้งาน C เพียงเล็กน้อยเท่านั้น

ฉันไม่รู้จัก C ฉันไม่ได้ใช้ C ฉันไม่ใช่สมาชิกของชุมชน C แต่ถึงกระนั้นฉันก็รู้มากกว่าคอมไพเลอร์ที่คุณพูดถึง

สิ่งแรกที่สำคัญที่สุดคือคอมไพเลอร์ซึ่งอาจเป็นดาวแคระทั้ง GCC และ Clang บนเดสก์ท็อป: Microsoft Visual C แม้จะมีการโจมตีที่ทั้ง OSX และ Linux ได้ทำบนเดสก์ท็อปและตลาดที่ iOS และ Android นั้น "ถูกขโมย" ห่างจากผู้ใช้เดสก์ท็อปดั้งเดิมดั้งเดิม Windows ยังคงเป็นระบบปฏิบัติการเดสก์ท็อปที่โดดเด่นและโปรแกรมเดสก์ท็อป C ส่วนใหญ่ของ Windows อาจถูกรวบรวมโดยใช้เครื่องมือของ Microsoft

ตามเนื้อผ้าผู้ขายระบบปฏิบัติการและผู้ขายชิปทุกคนมีคอมไพเลอร์ของตัวเอง Microsoft ในฐานะผู้จำหน่ายระบบปฏิบัติการมี Microsoft Visual C. IBM ในฐานะผู้จำหน่ายระบบปฏิบัติการและผู้จำหน่ายชิปมี XLC (ซึ่งเป็นระบบคอมไพเลอร์เริ่มต้นสำหรับ AIX และคอมไพเลอร์ที่รวบรวมทั้ง AIX และ i / OS) . Intel มีคอมไพเลอร์เป็นของตัวเอง Sun / Oracle มีคอมไพเลอร์เป็นของตัวเองใน Sun Studio

จากนั้นมีผู้จำหน่ายคอมไพเลอร์ที่มีประสิทธิภาพสูงเช่น PathScale และ The Portland Group ซึ่งมีคอมไพเลอร์ (และไลบรารี OpenMP) ที่ใช้สำหรับการคำนวณตัวเลข

Digital Mars ยังอยู่ในธุรกิจ ฉันเชื่อว่า Walter Bright มีความแตกต่างที่ไม่เหมือนใครในการเป็นคนเดียวในโลกที่สามารถสร้างคอมไพเลอร์ C ++ คุณภาพการผลิต (ส่วนใหญ่) ได้ด้วยตัวเอง

สุดท้ายนี้เรามีคอมไพเลอร์ลิขสิทธิ์เฉพาะสำหรับไมโครคอนโทรลเลอร์แบบฝัง IIRC มีไมโครคอนโทรลเลอร์ขายมากกว่าเดสก์ท็อป, มือถือ, เซิร์ฟเวอร์, เวิร์กสเตชันและเมนเฟรมซีพียูทุกปีที่ขายกันในประวัติศาสตร์ของการคำนวณรวมกัน ดังนั้นสิ่งเหล่านี้ไม่ใช่ผลิตภัณฑ์เฉพาะกลุ่ม

การกล่าวถึงกิตติมศักดิ์จะออกไปที่TruffleCซึ่งเป็นล่าม C (!) ที่ทำงานบน JVM (!) ที่เขียนโดยใช้เฟรมเวิร์กล่าม Truffle AST ที่ช้ากว่า GCC และ Clang เพียง 7% เท่านั้น เกมเกณฑ์มาตรฐานภาษาคอมพิวเตอร์และเร็วกว่าบน microbenchmarks เมื่อใช้ TruffleC ทีม Truffle สามารถรับรุ่น JRuby + Truffle เพื่อเรียกใช้ส่วนขยาย Ruby C ได้เร็วกว่าการใช้ C Ruby จริง!

ดังนั้นนี่คือการติดตั้งใช้งาน 6 รายการนอกเหนือจากรายการที่คุณระบุไว้ซึ่งฉันสามารถตั้งชื่อปิดส่วนบนของหัวของฉันโดยไม่ต้องรู้อะไรเกี่ยวกับ C.


1
นอกเหนือจาก Microsoft Visual C คอมไพเลอร์ C ส่วนใหญ่ที่คุณพูดถึงนั้นไม่ค่อยได้ใช้
Basile Starynkevitch

6
MSVC เป็นคอมไพเลอร์ C ++ ตัวใหญ่ แต่สำหรับ C ยากที่จะใช้และติดอยู่ใน C89 อย่างถาวร คอมไพเลอร์ไมโครคอนโทรลเลอร์มักจะเป็นเป้าหมายเฉพาะติดอยู่ใน C89 และแปลกประหลาด; TruffleC ยังไม่พร้อมใช้งาน (แต่น่าสนใจขอบคุณ) Pathscale และ Digital Mars ดูเหมือนจะเป็นตัวอย่างของคู่ต่อสู้ที่ฉันกำลังมองหา
Leushenko

8
@Mario ความหมายของฉันไม่ใช่ C89 ที่เสีย แต่ C89 ไม่ใช่รูปแบบที่ทันสมัยของภาษา และนั่นหมายความว่าคอมไพเลอร์น้อยลงที่มีอยู่
Leushenko

6
@Leushenko MSVC ไม่ติดอย่างถาวรใน C89 มีการพูดคุยและควรเพิ่มคุณสมบัติ C99 เพิ่มเติม สำหรับผู้เริ่มต้นห้องสมุด C99 ส่วนใหญ่ได้รับการสนับสนุนตั้งแต่ MSVC 2015 และมีคุณสมบัติภาษาไม่กี่ภาษา (ส่วนใหญ่เป็นสิ่งที่จำเป็นสำหรับ C ++ 11)
Morwenn

5
@ Morwenn: นโยบายของ Microsoft ดูเหมือนว่า C99 จะแก้ปัญหาที่ C ++ ยังไม่ได้แก้ไขและถ้าคุณกำลังเขียนโปรแกรมระบบคุณควรใช้ C-like subset C ++ (อะไรก็ตามที่ไม่ต้องการ runtime หรือ ที่ซึ่งคุณไม่สามารถควบคุมได้ว่าคอมไพเลอร์จะนำสิ่งใดมาใช้สิ่งสำคัญหากคุณต้องการตรวจสอบให้แน่ใจว่าโค้ดหรือข้อมูลไม่ได้ถูกเพจออกจากสถานะที่ปิดใช้งานการเพจ) คุณลักษณะเฉพาะจาก C99 จะเป็นสิ่งที่จำเป็นในสเปค C ++ ในภายหลังและฟีเจอร์ที่ไม่ต้องใช้สมอง
Mike Dimmick

8

คุณต้องการคอมไพเลอร์จำนวนเท่าใด

หากพวกเขามีชุดคุณสมบัติที่แตกต่างกันคุณจะสร้างปัญหาการพกพา หากพวกเขาเป็นสินค้าที่คุณเลือก "เริ่มต้น" (GCC, เสียงดังกราวหรือ VS) หากคุณสนใจเกี่ยวกับประสิทธิภาพ 5% ที่ผ่านมาคุณมีเกณฑ์มาตรฐาน

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

โปรดทราบว่านี่อาจแตกต่างกันมากในแต่ละภาษา Java มี toolchain ของ Sun / Oracle และ GNU Python มีคอมไพเลอร์หลายตัวซึ่งไม่ได้รับความเคารพอย่างแท้จริงเมื่อเทียบกับล่ามมาตรฐาน Rust and Go มีการใช้งานเพียงหนึ่งครั้งเท่านั้น C # มี Microsoft และ Mono


1
เห็นได้ชัดว่ามีเหตุผลที่น่าสนใจมากกว่าในการพัฒนา ML compiler ... ฉันแค่คิดว่าชุมชน C อาจใหญ่กว่าสามลำดับความสำคัญจะทำให้เกิดผลที่สมดุล แต่คุณอาจจะถูกต้องยังคงเป็น1000 * 0 0
Leushenko

การสร้างคอมไพเลอร์ใหม่มักจะเชื่อมโยงกับการกระจายตัวของชุมชน (สาเหตุหรือสาเหตุ) ตัวอย่างเช่นตัวแบ่ง egcs vs gcc นอกจากนี้ความเข้ากันได้ของแหล่งสัญญาณ C มีแนวโน้มต่ำกว่า 100%
pjc50

@ pjc50: วิธีการเขียนมาตรฐานแบ่งย่อย C อย่างมีประสิทธิภาพเป็นภาษา disjoint ตามสิ่งต่าง ๆ เช่นประเภทพื้นฐานintและจะต้องใช้คอมไพเลอร์ต่าง ๆ ในการแปลซอร์สโค้ดเดียวกันในรูปแบบที่แตกต่างกันมาก
supercat

5
ฉันเชื่อว่า Go มีการใช้งานสองแบบ ( 6g/ 8g/ … toolchain และ gccgo) เคยมีการใช้งานเชิงพาณิชย์ที่น่าสนใจอย่างมากที่เรียกว่า erGo ซึ่งเป็นก) การติดตั้ง Windows แบบดั้งเดิมของ Go ในเวลาที่ทั้ง gccgo และคอมไพเลอร์ Go ดั้งเดิมทำงานได้ดีบน Windows ข) การวางเดิมพันของ Go นาน ก่อนที่มันจะกลายเป็น 1.0 และ c) การดำเนินการครั้งแรกของ Go ที่เขียนใน Go (gccgo และ 6g / 8g นั้นเขียนไว้ใน C) อย่างไรก็ตามทั้งโครงการและ บริษัท ก็หายไปก่อนที่พวกเขาจะออกจากเบต้าปิด
Jörg W Mittag

6

C / C ++ มีเอกลักษณ์ในภาษาที่คอมไพล์ซึ่งมันมีการใช้งานหลัก 3 อย่างของข้อกำหนดทั่วไป

ตามกฎในการยกเลิกสิ่งที่ไม่ได้ใช้มากภาษาที่คอมไพล์ทุกภาษาจะมีค่า 0 ต่อ 1

และฉันคิดว่าจาวาสคริปต์เป็นเหตุผลเดียวที่คุณต้องระบุ 'รวบรวม'


2
ป้ายกำกับ "C" ถูกนำไปใช้กับหลายภาษา บางคนกำหนดรหัสuint16_t a=48000u; unsigned uint32_t b=(a*a)/2;เป็นการกำหนดให้bกับค่า 8192 บางคนกำหนดว่าเป็นการกำหนด 1152000000 ทุกวันนี้ส่วนใหญ่คิดว่ามันเป็นพฤติกรรมที่ไม่ได้กำหนดและมีแนวโน้มที่จะเก็บ 3299483648 แต่ไม่มีสัญญาในเรื่องนั้น
supercat

1
@supercat: อ้าสิ่งที่ดีแปลก ๆ ที่มีมากเกินและกฎการส่งเสริมการขายจำนวนเต็ม มันบานพับกับการใช้งาน2หรือ2uเห็นได้ชัด
Zan Lynx

1
@ZanLynx: ผมไม่คิดว่ามีกรณีใดที่ 2 เมื่อเทียบกับ 2u ถูกต้องตามกฎหมายที่สำคัญ; เฉพาะกรณีที่ฉันรู้ว่ามันอาจมีความสำคัญเกี่ยวข้องกับพฤติกรรมที่ไม่ได้กำหนดทั้ง 2 และ 2u
supercat

3
@supercat: คุณจะรับพฤติกรรมที่ไม่ได้กำหนดได้/2uอย่างไร มีการกำหนดโอเวอร์โฟลที่ไม่ได้ลงนามไว้ (เป็นโมดูโล 2 ^ N สำหรับการปรับใช้ในการปรับใช้ N) แต่การแบ่งไม่สามารถทำล้นได้
MSalters

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

5

ดังนั้นภาษาเป้าหมายของคุณคืออะไร

คอมไพเลอร์ SML มักจะกำหนดเป้าหมายไปที่ C หรือบางอย่างเช่น LLVM (หรือตามที่เห็นในลิงก์ของคุณ, JVM หรือ JavaScript)

หากคุณกำลังคอมไพล์ C นั่นไม่ใช่เพราะคุณกำลังจะไปที่ JVM คุณกำลังจะทำอะไรที่แย่กว่าซีไกล จากนั้นคุณจะต้องทำซ้ำหลาย ๆ ครั้งสำหรับแพลตฟอร์มเป้าหมายทั้งหมดของคุณ

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


SML / NJ และ PolyML กำลังรวบรวมรหัสเครื่อง ...
Basile Starynkevitch

2
ขนาด int "พฤติกรรมที่ไม่ได้กำหนด" เป็นอย่างไร และทำไม UB ถึงเป็นผู้ขายคอมไพเลอร์ล่ะ? ภาระที่แท้จริงเพียงอย่างเดียวสำหรับผู้เขียนคอมไพเลอร์คือความกว้างของอินเทอร์แอคทีฟถูกกำหนดไว้ซึ่งไม่ได้ระบุไว้ดังนั้นคุณต้องทำเอกสารสิ่งที่คุณทำ
MSalters

@MSalters ในความเป็นจริงผู้เขียนคอมไพเลอร์สำหรับแพลตฟอร์มที่จัดตั้งขึ้นมีภาระในการจับคู่สิ่งที่คนอื่น ๆ ที่ไปก่อนพวกเขา บางครั้งสิ่งนี้ถูกทำเป็นเอกสารและเป็นมาตรฐาน แต่บางครั้งก็ไม่ใช่ มันง่ายที่จะหาขนาดที่ int แต่ยากที่จะหาสิ่งที่ทำด้วยค่าการลงทะเบียนและที่เก็บข้อโต้แย้งเมื่อเรียกใช้ฟังก์ชั่น (ซึ่งอาจเปลี่ยนแปลงได้ขึ้นอยู่กับชนิดอาร์กิวเมนต์และประเภทกลับมาของฟังก์ชั่น) โครงสร้างเค้าร่าง ฯลฯ
Random832

@MSalters คนส่วนใหญ่คาดว่าintจะเป็น 32 หรือ 64 บิต แต่อาจมีขนาดเล็กเท่ากับ 16 บิต มันไม่ยากเลยที่จะสร้างตัวเลขนอกช่วง[−32767, +32767]และintล้นคือ UB นอกจากนี้ยังมีchar/ shortได้รับการเลื่อนตำแหน่งint หรือ unsigned intขึ้นอยู่กับว่าintสามารถเป็นตัวแทนของทุกค่าของประเภทต้นฉบับซึ่งสามารถเรียกการแปลงจากintไปยังunsigned intหากตัวถูกดำเนินการมีประเภทที่แตกต่างกันและได้รับการแปลงแตกต่างกันรวมทั้งการแปลงอื่น ๆ .
Doval

@Malters มีขนาดที่พอเหมาะกับขนาดของประเภทมาตรฐานและการแปลงโดยนัยที่ฉันวางเดิมพันสำหรับโปรแกรม C ที่ไม่สำคัญมีตัวเลือกขนาดเต็มที่ถูกต้องตามกฎหมายที่จะทำให้มันผิดหรือทำให้ไม่ได้กำหนด พฤติกรรม.
Doval
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.