Clang vs GCC สำหรับโครงการพัฒนา Linux ของฉัน


175

ฉันอยู่ในวิทยาลัยและสำหรับโครงการที่เราใช้ C. เราได้สำรวจ GCC และ Clang และ Clang ดูเหมือนจะเป็นมิตรต่อผู้ใช้มากกว่า GCC เป็นผลให้ฉันสงสัยว่าข้อดีหรือข้อเสียคือการใช้เสียงดังกราวเมื่อเทียบกับ GCC สำหรับการพัฒนาใน C และ C ++ บน Linux?

ในกรณีของฉันนี้จะใช้สำหรับโปรแกรมระดับนักเรียนไม่ใช่การผลิต

ถ้าฉันใช้ Clang ฉันควรดีบักด้วย GDB และใช้ GNU Make หรือใช้ดีบักเกอร์อื่นแล้วสร้างยูทิลิตี้?


7
เท่าที่ฉันบอกได้เสียงดังยังคงห่างไกลจาก "ผู้สูงวัย" โดยเฉพาะอย่างยิ่งเกี่ยวกับการสนับสนุนห้องสมุดมาตรฐาน อย่างไรก็ตามมันมีข้อความแสดงข้อผิดพลาดที่ยอดเยี่ยมดังนั้นคุณสามารถเข้าถึงข้อผิดพลาดของผู้แปลได้โดยการลองใช้รหัสบน Clang เสียงดังยังสามารถคอมไพล์ C ++ ถึง C ได้ฉันเชื่อ
Kerrek SB

3
@KerrekSB: องค์ประกอบของ "การสนับสนุนห้องสมุดมาตรฐาน" หายไปจากเสียงดังกราว
สตีเฟ่นแคนนอน

2
@StephenCanon: ครั้งสุดท้ายที่ฉันลองฉันต้องใช้ libstdc ++ (ซึ่งไม่ได้เป็นส่วนหนึ่งของ Clang เท่าที่ฉันเข้าใจ) และเมื่อวันก่อนเรามีปัญหานี้ อย่างไรก็ตามฉันไม่ได้ตามขอบเลือดออกดังนั้นมุมมองของฉันอาจล้าสมัยไปหมด
Kerrek SB

4
@KerrekSB: เกี่ยวกับลิงค์ของคุณเสียงดังกังวานไม่ทำงานบน Windows แท้ๆ มันใช้งานได้ใน MinGW ในส่วนของห้องสมุดมาตรฐานนั้นไม่มีส่วนใดของห้องสมุดมาตรฐานที่แท้จริงของ Clang ในขณะนี้ เสียงดังกราวมาพร้อมกับ libc ++ บน OSX แต่ libc ++ ไม่ได้รับการพอร์ตอย่างเต็มที่ในสภาพแวดล้อมอื่นดังนั้นในเสียงดังกราวเหล่านั้นจำเป็นต้องติดตั้งการใช้งานไลบรารี่มาตรฐานอื่น บน Linux, libstdc ++ ใช้งานได้
Matthieu M.

1
@KerrekSB: รองรับ C ++ 98 ได้ 100% ส่วนใหญ่ได้รับการสนับสนุน C ++ 11 (ล่าสุดฉันตรวจสอบ<atomic>ไม่ได้รับการสนับสนุนบางทีสิ่งเล็ก ๆ อื่น ๆ หายไป ... ฉันไม่สามารถใช้งานได้
James McNellis

คำตอบ:


122

แก้ไข:

พวก gcc ช่วยปรับปรุงประสบการณ์การวินิจฉัยใน gcc (การแข่งขัน ah) จริงๆ พวกเขาสร้างหน้าวิกิพีเดียที่จะแสดงมันนี่ gcc 4.8 ตอนนี้มีการวินิจฉัยที่ดีเช่นกัน (gcc 4.9x เพิ่มการรองรับสี) เสียงดังกราวยังคงเป็นผู้นำ แต่ช่องว่างกำลังปิด


เดิม:

สำหรับนักเรียนฉันขอแนะนำ Clang โดยไม่มีเงื่อนไข

ประสิทธิภาพในแง่ของโค้ดที่สร้างขึ้นระหว่าง gcc และ Clang นั้นไม่ชัดเจน (แม้ว่าฉันคิดว่า gcc 4.7 ยังมีความเป็นผู้นำฉันยังไม่ได้เห็นข้อสรุปมาตรฐาน) แต่สำหรับนักเรียนที่จะเรียนรู้มันไม่สำคัญเลย

ในทางกลับกันการวินิจฉัยที่ชัดเจนของ Clang นั้นง่ายสำหรับผู้เริ่มต้นในการตีความ

ลองพิจารณาตัวอย่างง่ายๆนี้:

#include <string>
#include <iostream>

struct Student {
std::string surname;
std::string givenname;
}

std::ostream& operator<<(std::ostream& out, Student const& s) {
  return out << "{" << s.surname << ", " << s.givenname << "}";
}

int main() {
  Student me = { "Doe", "John" };
  std::cout << me << "\n";
}

คุณจะสังเกตได้ทันทีว่าเซมิโคลอนหายไปหลังจากนิยามของStudentคลาสใช่ไหม?

ดีGCC สังเกตเห็นมันมากเกินไปหลังจากที่แฟชั่น:

prog.cpp:9: error: expected initializer before ‘&’ token
prog.cpp: In function int main()’:
prog.cpp:15: error: no match for operator<<’ in std::cout << me
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:112: note: candidates are: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>& (*)(std::basic_ostream<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:121: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ios<_CharT, _Traits>& (*)(std::basic_ios<_CharT, _Traits>&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:131: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:169: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:173: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:177: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:97: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:184: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:111: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:195: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:204: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:208: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:213: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:217: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:225: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/ostream:229: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.3.4/include/g++-v4/bits/ostream.tcc:125: note:                 std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_streambuf<_CharT, _Traits>*) [with _CharT = char, _Traits = std::char_traits<char>]

และเสียงดังกราวก็ไม่ได้นำแสดงโดยที่นี่เหมือนกัน แต่ก็ยัง:

/tmp/webcompile/_25327_1.cc:9:6: error: redefinition of 'ostream' as different kind of symbol
std::ostream& operator<<(std::ostream& out, Student const& s) {
     ^
In file included from /tmp/webcompile/_25327_1.cc:1:
In file included from /usr/include/c++/4.3/string:49:
In file included from /usr/include/c++/4.3/bits/localefwd.h:47:
/usr/include/c++/4.3/iosfwd:134:33: note: previous definition is here
  typedef basic_ostream<char>           ostream;        ///< @isiosfwd
                                        ^
/tmp/webcompile/_25327_1.cc:9:13: error: expected ';' after top level declarator
std::ostream& operator<<(std::ostream& out, Student const& s) {
            ^
            ;
2 errors generated.

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


2
อืม ... ครั้งสุดท้ายที่ฉันตรวจสอบฉันอ่านบทความที่ตีพิมพ์มาตรฐานต่างๆซึ่งเสียงดังกราวดังขึ้นอย่างน่าตกใจเป่า gcc ออกมาจากน้ำในการทดสอบที่เคย ที่มา: clang.llvm.org/features.html#performance

31
@AscensionSystems: ระวังการทดสอบเหล่านั้นแสดงให้เห็นถึงประสิทธิภาพของไบนารี Clang นั้นเอง (และเมื่อไม่นานมานี้) ไม่ใช่ประสิทธิภาพของไบนารีที่คุณรวบรวม
Matthieu M.

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

4
@AscensionSystems: นี่คือบัลลังก์ล่าสุดที่ฉันทราบเมื่อเปรียบเทียบgcc 4.6 กับ llvm 3.0ซึ่งแสดงข้อดีสุทธิของ gcc โดยเฉลี่ย สิ่งที่น่าสนใจอีกอย่างคือDragonEgg bench , DragonEgg เป็นปลั๊กอินที่อนุญาตให้ใช้ gcc front-end (และอาจเป็น optimizer) จากนั้นแบ็กเอนด์ LLVM เพื่อสร้างรหัส
Matthieu M.

1
ครั้งล่าสุดที่ฉันตรวจสอบมาตรฐาน phoronix นั้นไม่น่าไว้วางใจมาก: ธงคอมไพเลอร์ไม่ได้รับการบันทึกอย่างถูกต้อง แต่ผลลัพธ์ที่แนะนำสิ่งต่าง ๆ ไม่ได้ถูกตั้งค่าอย่างเหมาะสม
Eamon Nerbonne

35

ณ ตอนนี้ GCC มีการสนับสนุนที่ดีขึ้นและสมบูรณ์มากขึ้นสำหรับคุณสมบัติ C ++ 11 กว่า Clang นอกจากนี้ตัวสร้างโค้ดสำหรับ GCC ทำงานได้ดีขึ้นกว่าแบบใน Clang (จากประสบการณ์ของฉันฉันไม่เคยเห็นการทดสอบแบบละเอียดใด ๆ เลย)

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

ทางเลือกที่จะใช้จริง ๆ ขึ้นอยู่กับสิ่งที่มีความสำคัญต่อคุณ ฉันให้ความสำคัญกับการสนับสนุน C ++ 11 และคุณภาพการสร้างรหัสมากกว่าที่ฉันให้ความสำคัญกับความสะดวกในการรวบรวม ด้วยเหตุนี้ฉันใช้ GCC สำหรับคุณการแลกเปลี่ยนอาจแตกต่างกัน


3
นี่คือบทความล่าสุดของ Phoronix เมื่อเปรียบเทียบGCC 4.6 กับ Clang 3.0รวมถึงบทความก่อนหน้านี้เฉพาะกับแพลตฟอร์มรถดันดิน ผู้ชนะคือหนึ่งหรืออีกคนหนึ่ง (ในบทความก่อนหน้า gcc 4.7 จะปรากฏขึ้นเช่นกัน) ดังนั้นฉันจึงพบว่ามันไม่ชัดเจนซึ่งทำงานได้ดีขึ้น
Matthieu M.

ทำไมไม่ใช้ทั้งคู่? เสียงดังกราวสำหรับการพัฒนาและ GCC สำหรับการผลิต
segfault

5
@segfault: นั่นคือสิ่งที่ฉันกำลังทำอยู่ในปัจจุบัน คำตอบนี้ค่อนข้างเก่าและไม่เป็นความจริงอีกต่อไป ทั้ง Clang และ GCC นั้นพัฒนาขึ้นอย่างมีนัยสำคัญตั้งแต่ที่ฉันเขียนมัน (โดยเฉพาะตอนนี้ Clang นั้นตรงกับการสนับสนุน C ++ 11 โดยรวมของ GCC และ GCC ได้ปรับปรุงข้อความแสดงข้อผิดพลาดและความเร็วในการรวบรวม) ตอนนี้ฉันขอแนะนำให้ใช้ทั้งคู่โดยมีความพึงพอใจเล็กน้อยต่อ Clang เนื่องจากซอร์สโค้ด Clang นั้นเข้าใจได้ง่ายกว่าแหล่ง GCC
Mankarse

23

ฉันใช้ทั้งคู่เพราะบางครั้งพวกเขาก็ให้ข้อความแสดงข้อผิดพลาดที่มีประโยชน์

โครงการ Python สามารถค้นหาและแก้ไข buglets ขนาดเล็กได้หลายรายการเมื่อหนึ่งในนักพัฒนาคอร์พยายามทดลองคอมไพล์ด้วย clang เป็นครั้งแรก


1
คุณมีความคิดอย่างไรกับการใช้เสียงดังกราวด์สำหรับการดีบักบิวด์ แต่ gcc สำหรับรีลีสที่ดีที่สุด?
Olical

5
มีเหตุผลที่จะพัฒนาด้วยเสียงดังกราวและปล่อยด้วย GCC แต่ให้แน่ใจว่าการปล่อย GCC ของคุณผ่านชุดทดสอบ (ทั้งที่มีและไม่มี NDEBUG)
Raymond Hettinger

2
ขอบคุณสำหรับคำตอบ ฉันได้ลองใช้มาซักพักแล้วก็ใช้งานได้ดีจริงๆ ฉันได้รับคำเตือนหลายชุดเช่นกันซึ่งเยี่ยมมาก
Olical

11

ฉันใช้ทั้ง Clang และ GCC ฉันพบว่า Clang มีคำเตือนที่มีประโยชน์ แต่สำหรับมาตรฐานการติดตามเรย์ของฉันเอง - ช้ากว่า 5-15% อย่างสม่ำเสมอจากนั้น GCC (ลองใช้ด้วยเม็ดเกลือแน่นอน แต่พยายามใช้การเพิ่มประสิทธิภาพแบบเดียวกัน สำหรับทั้ง).

ดังนั้นสำหรับตอนนี้ฉันใช้การวิเคราะห์แบบคงที่ของ Clang และการเตือนด้วยมาโครที่ซับซ้อน: (แม้ว่าตอนนี้คำเตือนของ GCC ค่อนข้างดี - gcc4.8 - 4.9)

ข้อควรพิจารณาบางประการ:

  • เสียงดังกังวานไม่มีการสนับสนุน OpenMP เฉพาะเรื่องถ้าคุณใช้ประโยชน์จากสิ่งนั้น แต่เนื่องจากฉันทำมันเป็นข้อ จำกัด สำหรับฉัน (*****)
  • การรวบรวมข้ามอาจไม่ได้รับการสนับสนุนเช่นกัน (FreeBSD 10 เช่นยังคงใช้ GCC4.x สำหรับ ARM) ตัวอย่างเช่น gcc-mingw นั้นมีอยู่ใน Linux ... (YMMV)
  • IDE บางตัวยังไม่สนับสนุนการแยกเอาต์พุตClangs ( QtCreator เช่น *****)แก้ไข: QtCreator ตอนนี้รองรับการส่งออกของ Clang
  • บางแง่มุมของ GCC ได้รับการจัดทำเป็นเอกสารที่ดีขึ้นและเนื่องจาก GCC ใช้งานได้นานกว่าและมีการใช้กันอย่างแพร่หลายคุณอาจพบว่าการขอความช่วยเหลือเกี่ยวกับคำเตือน / ข้อความแสดงข้อผิดพลาดง่ายขึ้น

***** - พื้นที่เหล่านี้กำลังอยู่ในระหว่างการพัฒนาและอาจได้รับการสนับสนุนในไม่ช้า


ฉันใช้ OpenMP ด้วยเช่นกัน แต่ฉันคิดว่าจะเปลี่ยนมาใช้ TBB ซึ่งฉันคิดว่าจะใช้กับ Clang ได้

1
TBB อาจเป็นทางเลือกที่ทำงานได้สำหรับ OpenMP ในบางกรณี (แต่สำหรับ C ++ เท่าที่ฉันสามารถบอกได้), สำหรับ C ที่ไม่รองรับ - สำหรับโครงการขนาดใหญ่การเปลี่ยนจาก OpenMP ไปเป็นอย่างอื่นอาจไม่คุ้มค่าโดยเฉพาะถ้า Clang จะ รองรับ OpenMP อยู่ดี
ideasman42

7

สำหรับโปรแกรมระดับนักเรียนนั้นเสียงดังกังวานนั้นมีประโยชน์อย่างมากตามค่าเริ่มต้นที่เข้มงวด มาตรฐาน C ตัวอย่างเช่น Hello World รุ่น K&R ต่อไปนี้ได้รับการยอมรับโดยไม่มีการเตือนจาก GCC แต่ถูกปฏิเสธโดย Clang พร้อมกับข้อความแสดงข้อผิดพลาดที่สื่อความหมาย:

main()
{
    puts("Hello, world!");
}

ด้วย GCC คุณจะต้องให้มัน-Werrorทำให้จริง ๆ แล้วเรื่องนี้ไม่ใช่โปรแกรม C89 ที่ถูกต้อง นอกจากนี้คุณยังต้องใช้c99หรือgcc -std=c99รับภาษา C99


8
gccโดยทั่วไปควรเรียกใช้อย่างน้อย-Wallซึ่งจะเตือนสำหรับโปรแกรมนี้ clangแม้ว่าจะมีคำเตือน / ข้อผิดพลาดที่ดี
caf

2
@caf: ซึ่งเป็นจุดที่ฉันพยายามทำกับ GCC คุณต้องผ่านตัวเลือก ออกนอกกรอบอาจทนต่อการสอนเกินไป
Fred Foo

นั่นอาจเป็นจริง แต่มันก็เป็นประเด็นเล็กน้อย สิ่งที่สำคัญกว่าคือคุณภาพของข้อความแสดงข้อผิดพลาด GCC 4.6 นั้นค่อนข้างดี แต่ฉันเข้าใจว่าเสียงดังกราวกำลังทำเวทมนต์จริงๆอยู่ที่นั่น
Kerrek SB

2
@dreamlax: จริง; นอกจากนี้ยังมีgnu99และและgnu++98 gnu++0xฉันคิดว่าสิ่งเหล่านั้นเป็นส่วนขยายของแท้แม้ว่าพวกเขาจะรวบรวมสอดคล้องกับรหัสมาตรฐาน ISO โดยไม่ต้องผูกปม นี่คือรายละเอียด: สำหรับ C , สำหรับ C ++
Kerrek SB

1
โปรแกรมนี้ไม่ควรสร้างข้อผิดพลาดหรือคำเตือน มันสอดคล้องกับมาตรฐาน
เส้นทาง Miles

3

ฉันคิดว่าเสียงดังกราวอาจเป็นทางเลือก

GCC และเสียงดังกราวมีความแตกต่างในการแสดงออกเช่น a+++++aกันและฉันได้รับคำตอบที่แตกต่างมากมายกับเพื่อนของฉันที่ใช้เสียงดังกราวบน Mac ในขณะที่ฉันใช้ gcc

GCC ได้กลายเป็นมาตรฐานและเสียงดังกราวอาจเป็นทางเลือก เนื่องจาก GCC มีเสถียรภาพมากและเสียงดังกราวยังอยู่ระหว่างการพัฒนา


5
เสียงดังกราวกำลังเตรียมตัวอย่างรวดเร็วเพื่อแทนที่ GCC อย่างสมบูรณ์ในโลกลินุกซ์และได้ทำเช่นนั้นในโลก BSD มันเข้ามาแทนที่ GCC ใน Mac เมื่อหลายปีก่อน เสียงดังกราวเป็นสิ่งที่ดี ฉันคิดว่า GCC สามารถเป็นทางเลือกส่วนตัวและฉันจะมีความสุขกับมัน
coder543

5
การแสดงออก +++++ a ไม่ได้ถูกกำหนดดังนั้นคาดว่าจะได้รับคำตอบที่แตกต่างกันในแต่ละคอมไพเลอร์หรือแม้แต่ในคอมไพเลอร์รุ่นเดียวกัน คุณสามารถได้ผลลัพธ์ที่ต่างกันสำหรับนิพจน์นั้นในคอมไพเลอร์เดียวกันเมื่อรวบรวมในเวลาต่างกัน นั่นคือสิ่งที่ "ไม่ได้กำหนด" หมายถึง
Lelanthran

1
a+++++aควรล้มเหลวเนื่องจากมีการแยกวิเคราะห์a ++ ++ + aซึ่งเป็นข้อผิดพลาดทางไวยากรณ์
Miles Rout

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