ภาษาการเขียนโปรแกรม C ถือเป็นภาษาระดับต่ำเมื่อมันออกมาหรือไม่


151

ปัจจุบันCถือเป็นภาษาระดับต่ำแต่ในยุค 70 ถือว่าเป็นระดับต่ำหรือไม่ เป็นคำที่ใช้งานอยู่แล้ว?

ภาษาระดับสูงที่ได้รับความนิยมจำนวนมากไม่ได้มีอยู่จนกระทั่งช่วงกลางยุค 80 และต่อไปดังนั้นฉันอยากรู้ว่าธรรมชาติระดับต่ำมีการเปลี่ยนแปลงอย่างไรในช่วงหลายปีที่ผ่านมา


13
ในฐานะที่เป็นหนึ่งจุดข้อมูลประมาณปี 1978 ที่ปรึกษาการเขียนโปรแกรมบางคนอธิบาย C ให้ฉันเป็นภาษาแอสเซมบลียกย่อง
Ben Crowell

7
@BenCrowell ผมไม่แน่ใจว่าสิ่งที่“สรรเสริญ” หมายความว่าในบริบทของคำสั่งของคุณ แต่ผมเคยมีประสบการณ์โทรเซลเซียสสากล (= แพลตฟอร์ม) ภาษาประกอบ
Melebius

13
ที่น่าสนใจมีกรณีที่จะทำให้C ไม่ใช่ภาษาระดับต่ำและตอนนี้ก็น้อยกว่าในยุค 70 เนื่องจากเครื่องเชิงนามธรรมของ C นั้นถูกลบออกจากฮาร์ดแวร์ที่ทันสมัยกว่าจาก PDP-11
Tom

5
เมื่อคิดถึงสิ่งนี้คุณอาจต้องการคิดถึงต้นกำเนิด - Unix เขียนใน C, c ทำงานบน Unix และ cross-compiles unix ไปยังแพลตฟอร์มอื่น สิ่งที่ไม่จำเป็นในการคอมไพล์ Unix นั้นไม่จำเป็นต้องมีค่าใช้จ่ายและเป้าหมายหลักของ C คือทำให้การเขียน / port คอมไพเลอร์ง่ายที่สุดเท่าที่จะทำได้ เพื่อจุดประสงค์นี้มันเป็นระดับที่ถูกต้องแน่นอนดังนั้นฉันไม่คิดว่า C เป็นระดับสูงหรือต่ำฉันคิดว่ามันเป็นเครื่องมือสำหรับพอร์ต Unix ที่เหมือนกับเครื่องมือ Unix เกือบทั้งหมดสามารถปรับตัวได้กับปัญหามากมาย
Bill K

4
เป็นที่น่าสังเกตว่าเสียงกระเพื่อมถูกประดิษฐ์ขึ้นในปี 1958
นายกรัฐมนตรี

คำตอบ:


144

วิธีตอบคำถามด้านประวัติศาสตร์ของคำถาม:

ปรัชญาการออกแบบได้รับการอธิบายในภาษา C Programming ซึ่งเขียนโดย Brian Kernighan และนักออกแบบ C Dennis Ritchie ซึ่งเป็น "K&R" ที่คุณอาจเคยได้ยิน คำนำของฉบับพิมพ์ครั้งแรกบอกว่า

C ไม่ใช่ภาษา "ระดับสูงมาก" และ "ใหญ่" ไม่ ...

และการแนะนำบอกว่า

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

รายการดำเนินต่อไปครู่หนึ่งก่อนที่ข้อความจะดำเนินต่อไป:

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

(ฉันมีฉบับที่สองตั้งแต่ปี 1988 เท่านั้น แต่ความคิดเห็นด้านล่างระบุว่าข้อความที่ยกมานั้นเหมือนกันในฉบับพิมพ์ครั้งแรกของปี 1978)

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


42
นี่คือคำตอบที่ยอดเยี่ยม! หลักฐานทางประวัติศาสตร์ที่ตรวจสอบได้ + ประจักษ์พยานของนักแสดงที่ดีที่สุดทราบถึงความหมายของระดับต่ำและสูงในช่วงเวลาที่ OP อ้างถึง โดยวิธีการที่ฉันยืนยันว่าคำพูดอยู่ในรุ่น 1978
Christophe

157

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

แม้ในภาษาระดับสูงของยุค 70 มันก็คุ้มค่าที่ชี้ให้เห็นว่า C อยู่ในระดับค่อนข้างต่ำ ภาษา C นั้นเป็นพื้น B บวกกับระบบพิมพ์อย่างง่ายและ B นั้นไม่ได้เป็นเพียงแค่เลเยอร์ไวยากรณ์เชิงโครงสร้าง / โครงสร้างที่สะดวกสำหรับการประกอบ เนื่องจากระบบประเภทนั้นเป็นแบบย้อนยุคด้านบนของภาษา B ที่ไม่ได้พิมพ์คุณยังคงสามารถใส่คำอธิบายประกอบประเภทออกในบางสถานที่และintจะถือว่า

C รู้ตัวว่ามีราคาแพงหรือยากที่จะใช้งานคุณลักษณะที่ได้รับการยอมรับอย่างดีในขณะนั้นเช่น

  • การจัดการหน่วยความจำอัตโนมัติ
  • ฟังก์ชั่นที่ซ้อนกันหรือปิด
  • OOP ขั้นพื้นฐานหรือ coroutines
  • ระบบประเภทที่แสดงออกมากขึ้น (เช่นประเภทที่ จำกัด ช่วง, ประเภทที่ผู้ใช้กำหนดเช่นประเภทบันทึก, การพิมพ์ที่แข็งแกร่ง, ... )

C มีคุณสมบัติที่น่าสนใจ:

  • รองรับการเรียกซ้ำ (เนื่องจากตัวแปรอัตโนมัติตามสแต็กเมื่อเทียบกับภาษาที่ตัวแปรทั้งหมดมีอายุการใช้งานทั่วโลก)
  • พอยน์เตอร์ฟังก์ชั่น
  • ชนิดข้อมูลที่ผู้ใช้กำหนดเอง (structs และ unions) ถูกนำไปใช้ในไม่ช้าหลังจากการเปิดตัวครั้งแรกของ C
  • การแทนค่าสตริงของ C (ตัวชี้ไปที่ตัวอักษร) เป็นการเพิ่มขึ้นอย่างมากของ B ซึ่งเข้ารหัสตัวอักษรหลายตัวเป็นคำเดียว
  • ไฟล์ส่วนหัวของ C เป็นแฮ็คที่มีประสิทธิภาพเพื่อให้หน่วยการรวบรวมมีขนาดเล็ก แต่ก็เกิดขึ้นเพื่อให้ระบบโมดูลที่เรียบง่าย
  • พอยน์เตอร์และตัวเลขไม่ จำกัด แบบประกอบของแอสเซมบลีเมื่อเทียบกับการอ้างอิงที่ปลอดภัยยิ่งขึ้น พอยน์เตอร์เป็นคุณสมบัติที่ไม่ปลอดภัยโดยเนื้อแท้ แต่ยังมีประโยชน์อย่างมากสำหรับการเขียนโปรแกรมระดับต่ำ

ในขณะที่ C ได้รับการพัฒนาภาษาที่เป็นนวัตกรรมอื่น ๆ เช่น COBOL, Lisp, ALGOL (ในภาษาต่าง ๆ ), PL / I, SNOBOL, Simula และ Pascal ได้รับการเผยแพร่แล้วและ / หรือมีการใช้อย่างกว้างขวางสำหรับโดเมนปัญหาที่เฉพาะเจาะจง แต่ภาษาที่มีอยู่ส่วนใหญ่มีไว้สำหรับการเขียนโปรแกรมเมนเฟรมหรือเป็นโครงการวิจัยเชิงวิชาการ เช่นเมื่อ ALGOL-60 ได้รับการออกแบบเป็นภาษาโปรแกรมสากลเป็นครั้งแรกเทคโนโลยีที่จำเป็นและวิทยาการคอมพิวเตอร์ที่จะใช้มันยังไม่มีอยู่ บางส่วนของภาษาเหล่านี้ (ภาษา ALGOL บางภาษา, PL / I, Pascal) มีไว้สำหรับการเขียนโปรแกรมระดับต่ำ แต่พวกเขามักจะมีคอมไพเลอร์ที่ซับซ้อนมากขึ้นหรือปลอดภัยเกินไป (เช่นไม่มีตัวชี้ที่ไม่ จำกัด ) ปาสกาลสะดุดตาขาดการสนับสนุนที่ดีสำหรับอาร์เรย์ความยาวตัวแปร

เมื่อเปรียบเทียบกับภาษาเหล่านั้น C ปฏิเสธคุณสมบัติ "หรูหรา" และราคาแพงเพื่อให้สามารถนำไปใช้ในการพัฒนาในระดับต่ำได้มากขึ้น C ไม่เคยเป็นโครงการวิจัยการออกแบบภาษาเป็นหลัก แต่มันเป็นหน่อของการพัฒนาเคอร์เนลของยูนิกซ์ในมินิคอมพิวเตอร์ PDP-11 ซึ่งค่อนข้าง จำกัด ทรัพยากร สำหรับช่อง (ภาษาระดับต่ำแบบมินิมอลสำหรับการเขียน Unix ด้วยคอมไพเลอร์แบบ pass เดียวที่ง่ายต่อการพอร์ต) C เป็นเลิศอย่างยิ่ง - และมากกว่า 45 ปีต่อมาก็ยังคงเป็นภาษาของการเขียนโปรแกรมระบบ


17
เพิ่มเพียงเล็กน้อยสำหรับผู้ที่ไม่ทราบสิ่งที่จำเป็นสำหรับตระกูล ALGOL และภาษาปาสคาลที่มีอยู่: ภาษาเหล่านั้นมีฟังก์ชั่นที่ซ้อนกันแบบ lexically ซึ่งคุณสามารถเข้าถึงตัวแปร (ในพื้นที่) ที่ประกาศในฟังก์ชั่นด้านนอก นั่นหมายความว่าคุณจะต้องรักษา "display" - อาร์เรย์ของพอยน์เตอร์ไปยังขอบเขตศัพท์ด้านนอก - ในแต่ละการเรียกใช้และส่งคืน (ที่เปลี่ยนระดับศัพท์) - หรือคุณต้องโยงขอบเขตศัพท์ศัพท์ขึ้นสแต็กและแต่ละการเข้าถึงตัวแปรดังกล่าว จำเป็นต้องมีหลาย hops ทางอ้อมขึ้นสแต็กเพื่อค้นหา เเพง! C ตะลึงสิ่งที่เกิดขึ้นทั้งหมด ฉันยังคิดถึงมันอยู่
davidbak

12
@davidbak: x86-64 System V ABI (หรือที่เรียกว่าแบบแผนบน Linux / OS X) กำหนด%r10เป็น "ตัวชี้โซ่แบบคงที่" ซึ่งเป็นสิ่งที่คุณกำลังพูดถึง สำหรับ C มันเป็นเพียงการลงทะเบียนเริ่มต้นแบบใหม่ที่เรียกว่า clobbered แต่ฉันเดาว่า Pascal จะใช้มัน (GNU C ฟังก์ชั่นที่ซ้อนกันใช้สำหรับการส่งผ่านตัวชี้ไปยังขอบเขตด้านนอกเมื่อฟังก์ชั่นดังกล่าวไม่ได้ inline (เช่นถ้าคุณทำชี้ทำงานกับมันเพื่อให้คอมไพเลอร์สร้าง trampoline รหัสเครื่องในกอง): การยอมรับของปกติ การใช้ r10 และ r11 )
Peter Cordes

2
@PeterCordes ที่น่าสนใจ! ปาสคาลยังคงใช้กันอย่างแพร่หลายเมื่อ System V ออกมา (แม้ว่าฉันจะไม่รู้ว่ากำหนด SysV ABI อย่างเป็นทางการ) คำตอบที่เชื่อมโยงของคุณมีข้อมูลมาก
davidbak

3
C มีประเภทที่ผู้ใช้กำหนด (struct / union) ส่วนที่เหลือของ "ฟีเจอร์" เหล่านั้นถูกทิ้งไว้ฉันสงสัยเพราะพวกมันมีการใช้งานที่เป็นศูนย์หรือเชิงลบ (เว้นแต่คุณจะเข้าร่วมการแข่งขันโค้ดที่สับสน :-)) เนื่องจากพวกเขาเบี่ยงเบนจากเป้าหมายในการรักษาภาษาทั้งง่ายและชัดเจน .
jamesqf

6
@jamesqf: แต่ต้น C ยังไม่มีการกำหนด struct ฉันเดาว่าคุณต้อง memcpy หรือคัดลอกสมาชิกแต่ละคนแทนที่จะเขียนa = b;เพื่อคัดลอก struct ทั้งหมดอย่างที่คุณสามารถทำได้ใน ISO C89 ดังนั้นในต้นซีประเภทที่ผู้ใช้กำหนดจึงเป็นคลาสที่สองแน่นอนและสามารถส่งผ่านโดยการอ้างอิงเป็นฟังก์ชัน args เท่านั้น ความเกลียดชังของ C ต่ออาร์เรย์และ ทำไม C ++ ถึงสนับสนุนการกำหนดค่าสมาชิกของอาร์เรย์ภายใน structs แต่ไม่ใช่โดยทั่วไป?
Peter Cordes

37

ในต้นปี 1970 C เป็นลมหายใจที่น่าตื่นตาของอากาศบริสุทธิ์โดยใช้โครงสร้างที่ทันสมัยอย่างมีประสิทธิภาพเพื่อให้ระบบ UNIX ทั้งหมดสามารถถูกเขียนใหม่จากภาษาแอสเซมบลีเป็น C ด้วยพื้นที่ว่างเล็กน้อยหรือปรับประสิทธิภาพการทำงาน ในเวลานั้นหลายคนเรียกมันว่าเป็นภาษาระดับสูง

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

สำหรับข้อมูลเพิ่มเติมโปรดอ่านบทความ BSTJ ดั้งเดิม:

ขอบคุณเดนนิส ขอให้คุณพักผ่อนอย่างสงบสุข


3
มันพิมพ์โดยทั่วไปและ wrapper nicer-syntax สำหรับชุด PDP ถ้าคุณถามฉัน
einpoklum


2
@ einpoklum ฉันมักจะเห็นด้วยกับที่ ฉันเรียนรู้ C ย้อนกลับไปเมื่อประมาณปี 1980 ที่มหาวิทยาลัยใน PDP-11 / 34a เมื่อมันเกิดขึ้นและมันถูกอธิบายโดยหนึ่งใน profs เป็น "ภาษาแอสเซมบลีแบบพกพา" อาจเป็นเพราะนอกเหนือจาก PDP-11 เรายังมีเครื่อง Superbrain CP / M หลายเครื่องในห้องปฏิบัติการที่มีคอมไพเลอร์ C อยู่ en.wikipedia.org/wiki/Intertec_Superbrain
dgnuff

2
นอกจากนี้ยังมีคำตอบที่ดีเยี่ยมจากหลักฐานทางประวัติศาสตร์ที่ตรวจสอบได้ (ว้าว! มีรุ่น K&R รุ่นก่อนวางจำหน่าย!)
Christophe

7
@einpoklum นี่มันค่อนข้างลึกซึ้งใช่ไหม ฉันมีโอกาสเขียนระบบและรหัสแอปพลิเคชันในช่วงกลางยุค 80 ในแอสเซมเบลอร์ (Z80 และ M68K) ซึ่งเป็น "แอสเซมเบลอร์แอสเซมเบลอร์" ที่เรียกว่า M (ไวยากรณ์ PDP11 ด้วยการลงทะเบียน 16 บิต , C เป็นภาษาระดับสูงแน่นอน: ผลผลิตของการเขียนโปรแกรม C เป็นลำดับความสำคัญสูงกว่าในแอสเซมเบลอร์! แน่นอนว่าไม่มีสตริง (SNOBOL), ไม่มีการสนับสนุนดาต้าไทล์พื้นเมือง (COBOL), ไม่มีรหัสการสร้างตัวเอง (LISP), ไม่มีคณิตศาสตร์ขั้นสูง (APL), ไม่มีวัตถุ (SIMULA) ดังนั้นเราสามารถยอมรับได้ว่ามันไม่สูงมาก
Christophe

21

อย่างที่ฉันเขียนไว้ที่อื่นในไซต์นี้เมื่อมีคนอ้างถึงรูปแบบการจัดการหน่วยความจำ malloc / free เป็น "การเขียนโปรแกรมระดับต่ำ"

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

สำหรับบริบทนี้เป็นช่วงต้น 90 ปีหลังจากที่ C ออกมา


ไลบรารีมาตรฐานไม่ได้เป็นเพียงสิ่งเดียวเท่านั้นนับตั้งแต่การสร้างมาตรฐานในช่วงปลายยุค 80 (เช่นกันตาม Unix APIs ที่มีอยู่) นอกจากนี้การเขียนโปรแกรมเคอร์เนล (ซึ่งเป็นโดเมนปัญหาดั้งเดิมของ C) ต้องใช้สิ่งระดับต่ำเช่นการจัดการหน่วยความจำด้วยตนเอง ในเวลา C ต้องเป็นภาษาการเขียนโปรแกรมระดับสูงสุดที่เคอร์เนลเขียนอย่างจริงจัง (ฉันคิดว่าทุกวันนี้เคอร์เนล NT ใช้ C ++ ในปริมาณที่พอใช้เช่นกัน)
amon

6
@ ไฮฉันใช้อัลกอล 60 สองภาษาฟอร์แทรนที่แตกต่างกันสองภาษาและภาษาเบสิกต่าง ๆ หลายภาษาย้อนกลับไปในทศวรรษ 1970 และไม่มีภาษาใดที่มีพอยน์เตอร์หรือตัวจัดสรรฮีป
โซโลมอนช้า

7
พูดอย่างเคร่งครัดคุณยังสามารถตั้งโปรแกรมโดยไม่ต้องmalloc()โทรbrk(2)หรือmmap(2)จัดการหน่วยความจำที่เกิดขึ้นด้วยตัวเองโดยตรง มันเป็น PITA ขนาดใหญ่ที่ไม่มีประโยชน์เท่าที่จะนึกออก (เว้นแต่คุณจะใช้สิ่งที่เหมือน Malloc) แต่คุณสามารถทำได้
เควิน

1
@amon - ยกเว้นเครื่องที่อิงตาม Burroughs ที่ตั้งโปรแกรมใน ALGOL จากล่างขึ้นบน ... และเร็วกว่า Unix ด้วย โอ้และยังไงก็ตาม Multics ซึ่งเป็นแรงบันดาลใจให้กับ Unix: เขียนเป็น PL / I คล้ายกับ ALGOL ระดับที่สูงกว่า C.
davidbak

6
จริงๆแล้วเหตุผลที่พวกเราไม่ได้ใช้ Multics ในวันนี้อาจจะมีอะไรเกี่ยวข้องกับความจริงที่ว่ามันวิ่งบนเมนเฟรมที่มีราคาแพงอย่างชั่วร้ายนั่นคือค่าใช้จ่ายเมนเฟรมทั่วไปในวันนี้บวกกับค่าใช้จ่ายเพิ่มเติมครึ่งตู้ของ ฮาร์ดแวร์พิเศษเพื่อใช้หน่วยความจำเสมือนพร้อมความปลอดภัย เมื่อ minicomputers แบบ 32 บิตเช่น VAX-11 ออกมาทุกคน แต่ธนาคารและรัฐบาลปลดประจำการจาก IBM และคนแคระทั้งเจ็ดและนำการประมวลผลขนาดใหญ่ไปยังคอมพิวเตอร์ "mini"
davidbak

15

มีคำตอบมากมายที่อ้างถึงบทความแรก ๆ ที่กล่าวถึงสิ่งต่างๆเช่น“ C ไม่ใช่ภาษาระดับสูง”

ฉันไม่สามารถต้านทานการซ้อนทับได้อย่างไรก็ตามหลาย ๆ ตัวถ้าไม่ใช่ HLL ส่วนใหญ่หรือทั้งหมดในเวลานั้น - Algol, Algol-60, PL / 1, Pascal - ให้การตรวจสอบขอบเขตของอาร์เรย์และการตรวจสอบตัวเลขล้น

ครั้งล่าสุดที่ฉันตรวจสอบบัฟเฟอร์และล้นจำนวนเต็มเป็นสาเหตุของช่องโหว่ความปลอดภัยจำนวนมาก ... ใช่ยังเป็นกรณี ...

สถานการณ์สำหรับการจัดการหน่วยความจำแบบไดนามิกนั้นซับซ้อนมากขึ้น แต่ถึงกระนั้นสไตล์ malloc / free ของ C ก็เป็นขั้นตอนที่ดีในด้านความปลอดภัย

ดังนั้นหากคำจำกัดความของ HLL ของคุณรวมถึง“ ป้องกันข้อบกพร่องระดับต่ำโดยอัตโนมัติ” อยู่ดีสถานะของการรักษาความปลอดภัยทางไซเบอร์จะแตกต่างกันมากอาจจะดีกว่าถ้า C และ UNIX ไม่ได้เกิดขึ้น


7
เนื่องจากฉันมีส่วนเกี่ยวข้องในการติดตั้ง Intel MPX และตัวชี้ / ขอบเขตการตรวจสอบคอมไพเลอร์ที่หมุนถ้ามันฉันสามารถอ้างอิงคุณเอกสารเกี่ยวกับประสิทธิภาพของพวกเขา: เป็นหลัก 5-15% ส่วนใหญ่เกี่ยวข้องกับการวิเคราะห์คอมไพเลอร์ที่แทบจะเป็นไปไม่ได้ในปี 1970 และ 1980 เมื่อเทียบกับการตรวจสอบที่ไร้เดียงสาที่อาจช้ากว่า 50% อย่างไรก็ตามฉันคิดว่ามันยุติธรรมที่จะพูดว่า C และ UNIX เริ่มทำงานในการวิเคราะห์เช่นนี้ภายใน 20 ปี - เมื่อ C กลายเป็นภาษาโปรแกรมที่นิยมมากที่สุดมีความต้องการความปลอดภัยน้อยกว่ามาก
Krazy Glew

9
@jamesqf ยิ่งกว่านั้นเครื่องจักรจำนวนมากก่อน C มีการสนับสนุนฮาร์ดแวร์พิเศษสำหรับการตรวจสอบขอบเขตและล้นจำนวนเต็ม เนื่องจาก C ไม่ได้ใช้ HW นั้นในที่สุดจึงเลิกใช้และลบออก
Krazy Glew

5
@jamesqf ตัวอย่างเช่น: MIPS RISC ISA แรกเริ่มนั้นยึดตามมาตรฐานของ Stanford ซึ่งเดิมเขียนเป็นภาษา Pascal ต่อมาย้ายไปที่ C เท่านั้นเนื่องจาก Pascal ตรวจสอบว่ามีจำนวนเต็มล้นลงนามดังนั้น MIPS จึงทำตามคำแนะนำเช่น ADD ประมาณปี 2010 ฉันทำงานที่ MIPS หัวหน้าของฉันต้องการลบคำแนะนำที่ไม่ได้ใช้ใน MIPSr6 ​​และจากการศึกษาพบว่าการตรวจสอบน้ำล้นนั้นแทบจะไม่เคยใช้เลย แต่กลับกลายเป็นว่า Javascript ทำการตรวจสอบดังกล่าว - แต่ไม่สามารถใช้คำแนะนำราคาถูกได้เนื่องจากขาดการสนับสนุนระบบปฏิบัติการ
Krazy Glew

3
@ KrazyGlew - มันน่าสนใจมากที่คุณนำสิ่งนี้มาตั้งแต่ใน C / C ++ การต่อสู้ระหว่างผู้ใช้และผู้เขียนคอมไพเลอร์ในเรื่อง "พฤติกรรมที่ไม่ได้กำหนด" เนื่องจากการล้นจำนวนเต็มลงนามกำลังร้อนขึ้นเนื่องจากนักเขียนคอมไพเลอร์ในปัจจุบันได้ใช้มนต์เก่า " โปรแกรมเลวร้ายยิ่งไม่มีบาป "และเปิดใช้งานได้มากถึง 11 โพสต์จำนวนมากบน stackoverflow และที่อื่นสะท้อนถึงสิ่งนี้ ...
davidbak

2
หาก Rust มี SIMD ภายในเช่น C อาจเป็นภาษาแอสเซมบลีแบบพกพาที่ทันสมัย C แย่ลงเรื่อย ๆ เนื่องจากภาษาแอสเซมบลีแบบพกพาเนื่องจากการเพิ่มประสิทธิภาพ UB เชิงรุกและความล้มเหลวในการเปิดเผยการดำเนินงานดั้งเดิมแบบใหม่ที่ซีพียูสมัยใหม่รองรับ (เช่น popcnt จำนวนศูนย์นำหน้า / ต่อท้าย, บิตย้อนกลับ, ไบต์ย้อนกลับ, อิ่มตัว) คณิตศาสตร์). การรวบรวมคอมไพเลอร์ C เพื่อสร้าง asm ที่มีประสิทธิภาพสำหรับสิ่งเหล่านี้บนซีพียูที่มีการรองรับ HW มักจะต้องการอินทรินภายในแบบพกพา มีเลียน popcnt popcntคอมไพเลอร์กับเป้าหมายโดยไม่ได้ดีกว่าสำนวนการรับรู้ที่จะได้รับ
Peter Cordes

8

พิจารณาภาษาที่เก่ากว่าและสูงกว่าที่มีอักษร C (1972):

Fortran - 1957 (ไม่สูงกว่า C มาก)

เสียงกระเพื่อม - 1958

Cobol - 1959

Fortran IV - 1961 (ไม่สูงกว่า C มาก)

PL / 1 - 1964

APL - 1966

บวกกับภาษาระดับกลางเช่น RPG (1959) ซึ่งส่วนใหญ่เป็นภาษาการเขียนโปรแกรมเพื่อแทนที่ระบบบันทึกยูนิตแบบใช้ปลั๊กอิน

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


2
หากคุณต้องการที่จะแสดงรายการเก่าภาษาที่สูงขึ้นอย่าลืม LISP
Deduplicator

@Dupuplicator - ฉันเพิ่มไปยังรายการ ฉันกำลังจดจ่อกับสิ่งที่ใช้กับเมนเฟรมของ IBM และฉันจำไม่ได้ว่า LISP กำลังเป็นที่นิยม แต่ APL ยังเป็นภาษาเฉพาะสำหรับเมนเฟรมของ IBM (ผ่านคอนโซลการแชร์เวลา) และ IBM 1130 คล้ายกับ LISP APL เป็นหนึ่งใน ไม่ซ้ำกันภาษาระดับสูงเช่นดูรหัสวิธีการเล็ก ๆ น้อย ๆ ก็จะใช้เวลาในการสร้างเกมของคอนเวย์ของชีวิตกับรุ่นปัจจุบันของ APL: youtube.com/watch?v=a9xAKttWgP4
rcgldr

2
ฉันจะไม่นับ RPG หรือ COBOL โดยเฉพาะอย่างยิ่งในระดับสูงอย่างน้อยก็ไม่ถึงกับ COBOL-85 เมื่อคุณเกาพื้นผิวของ COBOL คุณจะเห็นว่ามันเป็นคอลเลกชันของแมโครแอสเซมเบลอร์ขั้นสูงมาก เริ่มต้นด้วยมันขาดทั้งฟังก์ชั่นขั้นตอนและการเรียกซ้ำรวมถึงการกำหนดขอบเขตใด ๆ ที่เก็บข้อมูลทั้งหมดจะต้องประกาศที่ด้านบนสุดของโปรแกรมซึ่งจะนำไปสู่การโอเวอร์เรย์ที่ยาวมากหรือการใช้ซ้ำตัวแปรที่เจ็บปวด
idrougge

ฉันมีความทรงจำไม่ดีในการใช้ Fortran IV ฉันจำไม่ได้ว่ามันเป็น "ระดับที่สูงขึ้น" กว่า C.
DaveG

@idrougge - COBOL และ RPG และชุดคำสั่งเมนเฟรมรวมถึงการสนับสนุนอย่างเต็มรูปแบบสำหรับ BCD ที่บรรจุหรือไม่ได้บรรจุซึ่งเป็นข้อกำหนดสำหรับซอฟต์แวร์ทางการเงินในประเทศเช่นสหรัฐอเมริกา ฉันคิดว่าผู้ประกอบการที่เกี่ยวข้องเช่น "ย้ายที่สอดคล้องกัน" ให้อยู่ในระดับสูง RPG เป็นเรื่องผิดปกติที่คุณระบุการเชื่อมโยงระหว่างฟิลด์อินพุตดิบและฟิลด์เอาต์พุตที่จัดรูปแบบและ / หรือแอคคิวมูเลเตอร์ แต่ไม่ใช่ลำดับของการดำเนินการคล้ายกับการเขียนโปรแกรมปลั๊กอินที่ถูกแทนที่
rcgldr

6

คำตอบสำหรับคำถามของคุณขึ้นอยู่กับภาษา C ที่ถาม

ภาษาที่อธิบายไว้ในคู่มืออ้างอิงของ Dennis Ritchie ในปี 1974 เป็นภาษาระดับต่ำซึ่งให้ความสะดวกในการเขียนโปรแกรมภาษาระดับสูง ภาษาที่ได้จากภาษานั้นมีแนวโน้มที่จะเป็นภาษาโปรแกรมระดับต่ำ

เมื่อ 1989/1990 C Standard ถูกเผยแพร่อย่างไรก็ตามมันไม่ได้อธิบายภาษาระดับต่ำซึ่งได้รับความนิยมสำหรับการเขียนโปรแกรมเครื่องจริง แต่แทนที่จะอธิบายภาษาระดับสูงซึ่งอาจเป็น - แต่ไม่จำเป็นต้องเป็น - - ใช้งานในเงื่อนไขระดับต่ำกว่า

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

เพื่อให้เข้าใจถึงความแตกต่างนี้ให้พิจารณาว่าภาษาของ Ritchie และ C89 จะดูข้อมูลโค้ดได้อย่างไร:

struct foo { int x,y; float z; } *p;
...
p[3].y+=1;

บนแพลตฟอร์มที่ "char" คือ 8 บิต "int" คือ 16 บิต big-endian, "float" เป็น 32 บิตและโครงสร้างไม่มีข้อกำหนดการขยายหรือการวางแนวพิเศษดังนั้นขนาดของ "struct foo" คือ 8 ไบต์

ในภาษาของ Ritchie พฤติกรรมของคำสั่งสุดท้ายจะใช้ที่อยู่ที่เก็บไว้ใน "p" เพิ่ม 3 * 8 + 2 [ie 26] ไบต์ไปที่มันและดึงค่า 16 บิตจากไบต์ที่ที่อยู่นั้นและถัดไป เพิ่มหนึ่งลงในค่านั้นแล้วเขียนค่า 16 บิตนั้นกลับไปเป็นสองไบต์เดียวกัน พฤติกรรมจะถูกกำหนดเป็นการแสดงบนไบต์ที่ 26 และ 27 ตามด้วยที่แอดเดรส p โดยไม่คำนึงถึงชนิดของวัตถุที่ถูกเก็บไว้ที่นั่น

ในภาษาที่กำหนดโดยมาตรฐาน C ในกรณีที่ * p ระบุองค์ประกอบของ "struct foo []" ซึ่งตามด้วยองค์ประกอบที่สมบูรณ์ประเภทนี้อย่างน้อยสามรายการคำสั่งสุดท้ายจะเพิ่มสมาชิก y ของ องค์ประกอบที่สามหลังจาก * p พฤติกรรมจะไม่ถูกกำหนดโดยมาตรฐานในสถานการณ์อื่น ๆ

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

ภาษา C ที่คิดค้นโดย Dennis Ritchie จึงเป็นภาษาระดับต่ำและได้รับการยอมรับเช่นนี้ อย่างไรก็ตามภาษาที่คิดค้นโดยคณะกรรมการมาตรฐาน C นั้นไม่เคยเป็นภาษาระดับต่ำในกรณีที่ไม่มีการรับรองการดำเนินการที่ให้นอกเหนือไปจากเอกสารมาตรฐาน

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