C, C99, ANSI C และ GNU C ต่างกันอย่างไร?


124

ฉันได้เริ่มฝึกเขียนโปรแกรมบนcodechefและสับสนกับความแตกต่างระหว่าง C และ C99 C หมายถึงอะไรที่นี่? มันคือ C89? ตรวจสอบภาษาที่ด้านล่างของการส่งนี้ มีทั้ง C และ C99

ฉันพบสิ่งที่เรียกว่า GNU C บนอินเทอร์เน็ตมี C สำหรับระบบ linux / unix ต่างกันหรือไม่ สิ่งเหล่านี้เป็นไปตามมาตรฐาน C โดย ANSI หรือไม่ ฉันได้อ่านในบางสถานที่ "C99 เข้มงวด" นี่คืออะไร?

มีมาตรฐานอื่น ๆ ของ C ที่ใช้งานอยู่หรือไม่? มีสิ่งที่เรียกว่า C 4.3.2 หรือเป็นเวอร์ชัน gcc ที่ใช้อยู่ในปัจจุบัน?

แก้ไข:

นี้ , นี้ , นี้ช่วย ฉันจะค้นหาเพิ่มเติมและแก้ไขสิ่งที่ยังไม่มีคำตอบ

ฉันไม่ใช่มือใหม่ด้านการเขียนโปรแกรม ฉันรู้ว่าภาษาซีคืออะไร ฉันรู้ว่ามีมาตรฐาน C ที่แตกต่างกันโดย ANSI เช่น C89, C99 และ C11


@ ฉันจะไม่ค้นหามาก ฉันทำตอนนี้ ฉันจะทำมากกว่านี้ และแก้ไขคำถามเพิ่มเติม
Aseem Bansal

@ ฉันจะไม่พบ C99 ที่เข้มงวดหรือไม่และ C ใน codechef คือ C89 หรือ C. ดั้งเดิมที่ไม่ได้มาตรฐานรุ่นก่อนหน้านี้หรือไม่
Aseem Bansal

1
อย่าลืมPOSIX C :-)
pmg

คำตอบ:


217
  • ทุกอย่างก่อนกำหนดมาตรฐานโดยทั่วไปเรียกว่า "K&R C" ตามหลังหนังสือชื่อดังโดยมีเดนนิสริตชี่ผู้ประดิษฐ์ภาษาซีเป็นหนึ่งในผู้เขียน นี่คือ "ภาษาซี" ตั้งแต่ปีพ. ศ. 2515-2532

  • มาตรฐาน C ฉบับแรกได้รับการเผยแพร่ในปี 1989 ในประเทศสหรัฐอเมริกาโดยสถาบันมาตรฐานแห่งชาติของพวกเขา ANSI รุ่นนี้เรียกว่า C89 หรือ ANSI-C ตั้งแต่ปี 1989-1990 นี่คือ "ภาษาซี"

  • ปีต่อมามาตรฐานอเมริกันได้รับการยอมรับในระดับสากลและเผยแพร่โดย ISO (ISO 9899: 1990) รุ่นนี้เรียกว่า C90 ในทางเทคนิคเป็นมาตรฐานเดียวกันกับ C89 / ANSI-C อย่างเป็นทางการมันแทนที่ C89 / ANSI-C ทำให้ล้าสมัย ตั้งแต่ปี 1990-1999 C90 คือ "ภาษา C"

    โปรดทราบว่าตั้งแต่ปี 1989 ANSI ไม่ได้เกี่ยวข้องอะไรกับภาษา C โปรแกรมเมอร์ยังคงพูดถึง "ANSI C" โดยทั่วไปยังไม่ได้เบาะแสว่ามันหมายถึงอะไร ISO "เป็นเจ้าของ" ภาษา C ผ่านมาตรฐาน ISO 9899

  • การอัปเดตเล็กน้อยได้รับการเผยแพร่ในปี 1995 บางครั้งเรียกว่า "C95" นี่ไม่ใช่การแก้ไขครั้งใหญ่ แต่เป็นการแก้ไขทางเทคนิคที่มีชื่อว่า ISO / IEC 9899: 1990 / Amd.1: 1995 อย่างเป็นทางการ การเปลี่ยนแปลงหลักคือการแนะนำการรองรับอักขระแบบกว้าง

  • ในปี 2542 มาตรฐาน C ได้ผ่านการแก้ไขครั้งใหญ่ (ISO 9899: 1999) มาตรฐานเวอร์ชันนี้เรียกว่า C99 ตั้งแต่ปี 2542-2554 นี่คือ "ภาษาซี"

  • ในปี 2554 มาตรฐาน C มีการเปลี่ยนแปลงอีกครั้ง (ISO 9899: 2011) รุ่นนี้เรียกว่า C11 คุณสมบัติใหม่ต่างๆเช่น_Generic, _Static_assertและการสนับสนุนด้ายถูกเพิ่มเข้าไปในภาษา การอัปเดตให้ความสำคัญอย่างมากกับการจัดลำดับการประมวลผลแบบมัลติคอร์การประมวลผลและการแสดงออก ตั้งแต่ปี 2554-2560 นี่คือ "ภาษาซี"

  • ในปี 2560 C11 ได้รับการแก้ไขและแก้ไขรายงานข้อบกพร่องต่างๆ มาตรฐานนี้เรียกอย่างไม่เป็นทางการว่า C17 และเผยแพร่ในชื่อ ISO 9899: 2018 มันไม่มีคุณสมบัติใหม่เพียงแค่แก้ไข เป็นเวอร์ชันปัจจุบันของภาษา C


"C99 เข้มงวด" น่าจะหมายถึงการตั้งค่าคอมไพเลอร์ที่บังคับให้คอมไพเลอร์ทำตามมาตรฐานตามตัวอักษร มีคำที่สอดคล้องกับการใช้งานในมาตรฐาน C โดยพื้นฐานแล้วหมายถึง: "คอมไพเลอร์นี้ใช้ภาษา C ได้อย่างถูกต้อง" โปรแกรมที่ใช้ภาษา C ได้อย่างถูกต้องจะเรียกว่าอย่างเป็นทางการโปรแกรมสอดคล้องอย่างเคร่งครัด

"GNU C" สามารถหมายถึงสองสิ่ง คอมไพเลอร์ C ที่มาเป็นส่วนหนึ่งของ GNU Compiler Collection (GCC) หรืออาจหมายถึงการตั้งค่าเริ่มต้นที่ไม่ได้มาตรฐานที่คอมไพเลอร์ GCC C ใช้ หากคุณคอมไพล์gcc program.cแล้วคุณจะไม่คอมไพล์ตามมาตรฐาน C แต่เป็นการตั้งค่า GNU ที่ไม่ได้มาตรฐานซึ่งอาจเรียกว่า "GNU C" ตัวอย่างเช่นเคอร์เนล Linux ทั้งหมดถูกสร้างขึ้นใน GNU C ที่ไม่ได้มาตรฐานและไม่อยู่ในมาตรฐาน C

หากคุณต้องการที่จะรวบรวมโปรแกรมของคุณเป็นไปตามมาตรฐาน C gcc -std=c99 -pedantic-errorsคุณควรพิมพ์ แทนที่ c99 ด้วย c11 หากเวอร์ชัน GCC ของคุณรองรับ


8
การตั้งค่าคอมไพเลอร์ที่เข้มงวดอาจหมายถึง“ ปิดการใช้งานส่วนขยาย; ใช้เฉพาะภาษา C ที่กำหนดโดยมาตรฐาน "เช่นเดียวกับหรือมากกว่า" รวบรวมอย่างถูกต้อง " การยอมรับส่วนขยายของภาษานั้นถูกต้องสมบูรณ์ มีการกำหนดมาตรฐานเพื่อให้สามารถทำได้
Eric Postpischil

5
นอกจากนี้ยังมี C94 / C95 Amendment 1 ที่เพิ่มการรองรับอักขระที่กว้างขึ้นโดยส่วนใหญ่ ดูเพิ่มเติมรายการของมาตรฐานส่วนหัวของแฟ้มใน C และ C ++
Jonathan Leffler

2
คุณเขียนว่ามีหลายอย่างเปลี่ยนไปจาก C90 เป็น C99 ช่วยตั้งชื่อให้หน่อยได้ไหม
Martin Thoma

3
@ คุณ Lundin เชื่อมหนังสือผิดสำหรับ K&R; นี่เป็นรุ่นที่สองที่อธิบายถึงมาตรฐาน C89
Antti Haapala

5
ใช่ แต่ประเด็นคือนั่นไม่ใช่เวอร์ชันที่กำหนดภาษาการเขียนโปรแกรม C ได้ตรงประเด็น ไม่ใช่ว่าจะขายได้ทุกที่
Antti Haapala

7

ฉันต้องตอบสนองเกี่ยวกับ ANSI C แม้ว่า ANSI จะไม่ได้ทำอะไรเลย แต่คอมไพเลอร์ก็ยังคงถูกสร้างขึ้นมา ตัวอย่างเช่นคอมไพเลอร์ PIC XC16: "คอมไพเลอร์เป็นคอมไพเลอร์ที่ผ่านการตรวจสอบอย่างสมบูรณ์ซึ่งเป็นไปตามมาตรฐาน ANSI C ตามที่กำหนดโดยข้อกำหนด ANSI (ANSI x3.159-1989) และอธิบายไว้ใน The C Programming Language ของ Kernighan และ Ritchie's (รุ่นที่สอง) ... "ไม่ใช่การเขียนโปรแกรมทั้งหมดสำหรับคอมพิวเตอร์" ใหญ่ "เช่นพีซี การเขียนคอมไพเลอร์สำหรับต้นทุนอุปกรณ์ของคุณและการตรวจสอบเวลาต้นทุน & $ ANSI C ยังมีชีวิตและมีสุขภาพดีอยู่ในอุปกรณ์ฝังตัว / เรียลไทม์ของคุณ


4
  • ANSI C: ภาษา C ตัวแรกได้รับการกำหนดมาตรฐานโดยร่างกายที่เรียกว่า ANSI ในปี 1989 นั่นคือสาเหตุที่เรียกว่า c89

  • C99:
    ด้วยความต้องการจากข้อกำหนดของนักพัฒนาในปี 1999-2000 หรือมีการรวมคำหลักและคุณสมบัติเพิ่มเติมไว้ใน C99 (เช่นอินไลน์บูลีน .. เพิ่มฟังก์ชันไลบรารีแบบจุดลอยตัว)

  • GNU C: GNU เป็นระบบปฏิบัติการแบบยูนิกซ์ (www.gnu.org) และบางโครงการของ GNU ต้องการภาษาโปรแกรม C ตามมาตรฐาน ANSI C GNU ใช้คอมไพเลอร์ GCC (GNU Compiler Collection) เพื่อคอมไพล์โค้ด มีฟังก์ชั่น C library ซึ่งกำหนดการเรียกระบบเช่น malloc, calloc, exit ... ฯลฯ

ANSI C เป็นมาตรฐานที่ใช้โดยหรืออ้างถึงมาตรฐานอื่น ๆ


ทุกอย่างเกี่ยวกับ C99 ที่เข้มงวดและ C ในตัวแปลงสัญญาณคือ C89 หรือ C
Aseem Bansal

การแก้ไข: ANSI C เป็นมาตรฐานที่ล้าสมัยซึ่งอ้างถึงโดยเอกสารที่ล้าสมัยเท่านั้น ภาษา C เรียกว่า ISO C หรือถ้าคุณจะใช้ ISO / IEC 9899: 2011
Lundin

1

นอกเหนือจากคำตอบ Lundin

นี่คือสิ่งที่เดนนิสริชชี่พูด เมื่อถูกถาม

"เหตุใด K&R จึงไม่รอขั้นสุดท้ายมาตรฐาน ANSI ที่ได้รับการรับรองก่อนที่จะเขียน K&R ฉบับที่ 2"

เหตุใด K&R จึงไม่รอมาตรฐาน ANSI ที่ผ่านการรับรองขั้นสุดท้ายก่อนที่จะเขียน K&R 2nd edition ดูเหมือนว่าหนังสือเล่มนี้จะเป็นมาตรฐานที่ถูกต้องเพียงไม่กี่เดือนก่อนที่จะถูกแทนที่ด้วยมาตรฐานสุดท้ายของ ANSI ฉันรู้ว่ามีการเปลี่ยนแปลงที่สำคัญเล็กน้อยในช่วงปลายนี้ แต่ทำไมไม่รอสองสามเดือนและตรวจสอบให้แน่ใจว่าคุณทำถูกต้อง 100% แทนที่จะต้องเขียนฉบับที่ 3 เกือบจะในทันทีหรือล้าสมัยไปแล้ว?

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

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

เดนนิสริตชี่


1
Dennis Ritchie ไม่ทราบว่าจะใช้กฎนามแฝงอย่างไรเพื่อบอกเป็นนัยว่าคอมไพเลอร์ไม่ควรใช้ความพยายามใด ๆในการจดจำรูปแบบการใช้นามแฝงที่เป็นประโยชน์ แต่ให้เหตุผลว่าโปรแกรมเมอร์ที่มีโค้ดเสียโดยคอมไพเลอร์ป้านควร "ขอบคุณ" คอมไพเลอร์สำหรับ แสดงให้พวกเขาเห็นว่ารหัสของพวกเขา "มีข้อบกพร่อง" - มิฉะนั้นเขาอาจบอกคนที่ผลักดันกฎดังกล่าวเพื่อให้ชัดเจนว่าการปฏิเสธที่จะสนับสนุนการใช้นามแฝงที่เกินข้อกำหนดขั้นต่ำของมาตรฐานจะทำให้คอมไพเลอร์ไม่เหมาะสมสำหรับวัตถุประสงค์บางประการและความต้องการของโค้ดระดับต่ำสำหรับการใช้นามแฝงคือ ไม่ใช่ข้อบกพร่อง
supercat

@supercat ฉันไม่เข้าใจจริง ๆ ว่ากฎนามแฝงหมายถึงอะไรคุณสามารถช่วยฉันได้ไหม
Suraj Jain

1
แนวคิดดั้งเดิมคือโค้ดที่กำหนดเช่นint i; int test(double *p) { i=1; *p=2.0; return i; }คอมไพเลอร์ไม่จำเป็นต้องโหลดซ้ำiหลังจากเขียนถึง*pในโอกาสปิดที่pอาจมีที่อยู่ของi. เหมาะสมอย่างยิ่ง ปัญหาคือว่าคอมไพเลอร์ที่ทันสมัยใช้กฎเดียวกันที่จะปรับสมมติฐานที่เขียนไปlong*จะไม่ส่งผลกระทบต่อlong long, แม้ว่าทั้งสองชนิดมีขนาดเท่ากันและการเป็นตัวแทนและว่าแม้ว่าสองโครงสร้างแบ่งปันลำดับเริ่มต้นทั่วไปรหัสจะไม่ใช้ ตัวชี้ประเภทหนึ่งเพื่ออ่านสมาชิก CIS ที่เขียนผ่านอีกประเภทหนึ่ง
supercat

-2

คำถามนี้ไม่ได้ถูกค้นหาอย่างละเอียดบนอินเทอร์เน็ตเพื่อหาคำตอบอย่างไรก็ตามคุณอาจดูสิ่งนี้:

  1. C เป็นภาษาโปรแกรมสำหรับวัตถุประสงค์ทั่วไปที่พัฒนาโดย Dennis Ritchie ระหว่างปี 1969 ถึง 1973 ที่ AT&T Bell Labs
  2. C99 เป็นมาตรฐานของภาษา C ที่เผยแพร่โดย ISO และนำมาใช้โดย ANSI ในราวปี 2542
  3. GNU C เป็นเพียงส่วนเสริมของ c89 ในขณะที่มีการเพิ่มคุณสมบัติบางอย่างของ c99 แต่โดยรวมแล้วมันแตกต่างจากมาตรฐาน c99 ดังนั้นเมื่อรวบรวมใน gcc เราต้องป้อน-std=c99ซึ่งได้กล่าวไว้แล้วในคำตอบอื่น ๆ
  4. ANSI C เป็นชุดมาตรฐานต่อเนื่องที่ออกโดย ANSI

ฉันค้นหาในเน็ตตอนนี้ ฉันแก้ไขคำถามแล้ว ฉันรู้เกี่ยวกับมาตรฐาน C และ ANSI ก่อนโพสต์คำถาม ฉันมีความสับสนเกี่ยวกับบางสิ่งบางอย่าง ฉันจะพยายามทำให้แม่นยำมากขึ้น
Aseem Bansal

ทุกอย่างเกี่ยวกับ C99 ที่เข้มงวดและ C ใน codechef คือ C89 หรือ C
Aseem Bansal

4
คำตอบนี้มีข้อผิดพลาดมากมาย C99 เป็นมาตรฐานที่กำหนดโดย ISO ประมาณปี 2542 ภาษาซีเป็นมาตรฐานสากลมานาน 23 ปี ดังนั้น ANSI จึงไม่มีส่วนเกี่ยวข้องกับมันพวกเขาไม่ได้แตะมาตรฐาน C ใน 24 ปี ปัจจุบันพวกเขาเพียงพิมพ์และจัดจำหน่ายมาตรฐาน ISO สำหรับตลาดอเมริกา
Lundin

@ ลุนดินโอ้ !! ใช่จริงๆแล้วฉันเขียน "กำหนด" ซึ่งไม่ใช่ในกรณีนี้ควร "นำมาใช้" ที่นั่นฉันทำการแก้ไข ANSI ออกมาตรฐานแรกสำหรับวิธี C ย้อนกลับไปในปี 1989 ซึ่งได้รับการรับรองโดย ISO หลังจากนั้นมาตรฐานเกือบทั้งหมด ได้รับการเผยแพร่โดย ISO และนำมาใช้โดย ANSI และคำตอบนั้นสั้นเมื่อถูกถามดังนั้นฉันจึงพูดถึงบางสิ่งที่ทำให้คำตอบสั้น
0

1
โปรดทราบว่าgccการสนับสนุน-std=c89และ-std=gnu89และ-std=c99และ-std=gnu99(และรุ่นที่ทันสมัยพอที่สนับสนุน-std=c11และ-std=gnu11) ความแตกต่างคือจะทำอย่างไรกับส่วนขยายบน Standard C ที่พร้อมใช้งานโดยอัตโนมัติหรือเฉพาะเมื่อซอร์สสนับสนุนคอมไพเลอร์เพื่อให้มีมาโครที่เหมาะสม (เช่น-D_XOPEN_SOURCE=700)
Jonathan Leffler
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.