คอมไพเลอร์ C ++ ตัวแรกสามารถเขียนเป็น C ++ ได้อย่างไร?


48

Stroustrup อ้างว่า Cfront ซึ่งเป็นคอมไพเลอร์ C ++ ตัวแรกเขียนด้วย C ++ ( คำถามที่พบบ่อยของ Stroustrup )

อย่างไรก็ตามเป็นไปได้อย่างไรที่คอมไพเลอร์ C ++ แรกจะถูกเขียนใน C ++

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


6
en.wikipedia.org/wiki/Cfrontครอบคลุมปัญหาเล็กน้อย
christofr

คำตอบ:


57

กุญแจอยู่ตรงนี้:

คอมไพเลอร์ C ++ ตัวแรก (Cfront) เขียนด้วย C ++ ในการสร้างสิ่งนั้นฉันใช้ C เพื่อเขียน "C with Classes" -to-C preprocessor "C with Classes" เป็นภาษาถิ่น C ที่กลายเป็นบรรพบุรุษของ C ++ ทันที ตัวประมวลผลล่วงหน้าแปลว่า "C พร้อมคลาส" สร้าง (เช่นคลาสและตัวสร้าง) เป็น C มันเป็นตัวประมวลผลดั้งเดิมที่ไม่เข้าใจภาษาทั้งหมดเหลือการตรวจสอบประเภทส่วนใหญ่เพื่อให้คอมไพเลอร์ C ต้องทำและแปลเป็นรายบุคคล สร้างโดยไม่มีความรู้ที่สมบูรณ์ ฉันเขียน Cfront เวอร์ชันแรกใน "C with Classes"

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


5
+1 เพื่อรวมลิงก์ไปยังหนึ่งในนิทานที่ฉันชอบในสิ่งที่สามารถทำได้ (และไม่ควร)
jwernerny

3
คอมไพเลอร์ถูกเขียนในรหัส C ++ ที่ถูกต้อง แต่ใช้เพียงไม่กี่คุณสมบัติเต็มรูปแบบ C ++ ซึ่งได้รับการสนับสนุนโดยตัวประมวลผลล่วงหน้า "C with Classes" มันใช้ชุดย่อยของภาษาเต็มดังนั้นจึงรวบรวมผล (รุ่นที่ทำงานแรกของ Cfront) หลังจากทำตามขั้นตอน "bootstrap" เขาอาจไม่จำเป็นต้องใช้ preprocessor อีกครั้ง
joeytwiddle

2
@jwernerny - ฉันพบว่าบทความไม่พอใจเสมอ เขาคัดสรรส่วนที่ยากและไม่สำคัญที่สุด: "บั๊กจะจับคู่รหัสในคำสั่ง 'การเข้าสู่ระบบ' ของ UNIX รหัสการแทนที่จะคอมไพล์คำสั่งการเข้าสู่ระบบที่ไม่ถูกต้องเพื่อที่จะยอมรับรหัสผ่านที่เข้ารหัส " แต่สิ่งนี้จะเกิดขึ้นได้อย่างไร? เคยมีการแสดงให้เห็นจริง ๆ ไหม?
Detly

3
"นำไปสู่นวัตกรรมจำนวนมาก (และช่องโหว่ความปลอดภัยจำนวนมาก) ใน C": เท่าที่ฉันรู้ว่าเทคนิคเหล่านี้สามารถใช้ในภาษาใด ๆ ไม่ใช่เฉพาะใน C ดังนั้นภาษาอื่น ๆ จึงมีช่องโหว่ด้านความปลอดภัยเดียวกัน
Giorgio

2
@detly: ดูเหมือนเล็กน้อยในตอนนี้ แต่ในปี 1983 นี่เป็นการจู่โจมที่แปลกใหม่ทำให้สามารถปฏิบัติได้โดยขาดความหลากหลายในการนำไปปฏิบัติ เราเชื่อมั่นในระบบไบนารี่ได้มากกว่าเดิมบางส่วนเนื่องจากการรวบรวมทุกอย่างจากแหล่งที่มานั้นเป็นอุปสรรคที่ยิ่งใหญ่กว่าตอนนี้
Blrfl

17

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


9

ฉันคิดว่า BS ตอบคำถามนั้น:

คอมไพเลอร์ C ++ ตัวแรก (Cfront) เขียนด้วย C ++ ในการสร้างสิ่งนั้นฉันใช้ C เพื่อเขียน "C with Classes" -to-C preprocessor "C with Classes" เป็นภาษาถิ่น C ที่กลายเป็นบรรพบุรุษของ C ++ ทันที ตัวประมวลผลล่วงหน้าแปลว่า "C พร้อมคลาส" สร้าง (เช่นคลาสและตัวสร้าง) เป็น C มันเป็นตัวประมวลผลดั้งเดิมที่ไม่เข้าใจภาษาทั้งหมดเหลือการตรวจสอบประเภทส่วนใหญ่เพื่อให้คอมไพเลอร์ C ต้องทำและแปลเป็นรายบุคคล สร้างโดยไม่มีความรู้ที่สมบูรณ์

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

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


1
ดังนั้นโดยทั่วไปเมื่อเราคอมไพล์โปรแกรม C ++ มันจะถูกแปลงเป็น C หลังจากนั้นมันถูกแปลงเป็น C มันจะถูกคอมไพล์อีกครั้งเป็นรหัสเครื่อง?
Pacerier

@Pierier: แต่เดิมใช่ แต่ไม่ใช่ตอนนี้ฉันคิดว่า
Mike Dunlavey

ฉันไม่ค่อยเข้าใจความคิดเห็นของคุณ คุณหมายถึงตอนนี้มีคอมไพเลอร์ที่ข้ามขั้นตอนที่สองและเพียงแค่นำซอร์สโค้ด C ++ และคอมไพล์ไปยังรหัสเครื่อง?
Pacerier

7
@Pacerier: พวกเขาไม่ได้ไปที่ภาษาแอสเซมบลีหรือรหัสเครื่องโดยตรง โดยปกติแล้วพวกเขาจะไปที่การแสดงสื่อกลางที่ไม่ขึ้นอยู่กับเครื่องจักร (triples หรือ quads) และวิเคราะห์เพื่อการปรับให้เหมาะสม จากนั้นพวกเขาสร้างชุดประกอบหรือรหัสเครื่อง หากคุณรับหนังสือเกี่ยวกับการออกแบบคอมไพเลอร์(Aho & Ullman)ฉันแน่ใจว่าคุณจะพบว่ามันน่าสนใจ
Mike Dunlavey

1
เป็นสิ่งสำคัญที่จะต้องทราบว่าภาษา C ++ ที่เขากำลังสร้างนั้นเป็นเพียงเศษเสี้ยวของภาษาที่มีอยู่ในปัจจุบัน มันไม่มีเทมเพลตไม่มีไลบรารีใหม่ใช้ C แคสติ้งเท่านั้นและถ้าฉันจำได้ถูกต้องไม่มีข้อยกเว้น
Gort the Robot

2

ฉันจะเพิ่มคำตอบนี้เนื่องจากไม่มีคำตอบในประเด็นนี้

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

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

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