การรวบรวมโปรแกรม C ++ เกี่ยวข้องกับสามขั้นตอน:
การประมวลผลล่วงหน้า: ตัวประมวลผลล่วงหน้าใช้ไฟล์ซอร์สโค้ด C ++ และเกี่ยวข้องกับคำสั่ง#include
s, #define
s และตัวประมวลผลล่วงหน้าอื่น ๆ ผลลัพธ์ของขั้นตอนนี้คือไฟล์ "บริสุทธิ์" C ++ ที่ไม่มีคำสั่งพรีโปรเซสเซอร์
การคอมไพล์: คอมไพเลอร์ใช้เอาต์พุตของตัวประมวลผลล่วงหน้าและสร้างวัตถุไฟล์จากมัน
การลิงก์: ตัวลิงก์ใช้ไฟล์อ็อบเจ็กต์ที่สร้างโดยคอมไพเลอร์และสร้างไลบรารีหรือไฟล์ที่เรียกทำงานได้
กระบวนการเตรียมการผลิต
พรีโพรเซสเซอร์จัดการสั่ง preprocessorเช่นและ#include
#define
มันเป็นผู้ไม่เชื่อเรื่องพระเจ้าของไวยากรณ์ของ C ++ ซึ่งเป็นเหตุผลที่จะต้องใช้ด้วยความระมัดระวัง
มันทำงานบนไฟล์ต้นฉบับ C ++ ครั้งละหนึ่งไฟล์โดยแทนที่#include
คำสั่งด้วยเนื้อหาของไฟล์ที่เกี่ยวข้อง (ซึ่งมักจะเป็นเพียงการประกาศ) ทำการแทนที่มาโคร ( #define
) และเลือกส่วนต่าง ๆ ของข้อความ#if
ตาม#ifdef
และ#ifndef
คำสั่ง
ตัวประมวลผลล่วงหน้าทำงานบนสตรีมของโทเค็นการประมวลผลล่วงหน้า การแทนที่แมโครถูกกำหนดเป็นการแทนที่โทเค็นด้วยโทเค็นอื่น ๆ (ตัวดำเนินการ##
ช่วยให้สามารถรวมโทเค็นสองตัวเมื่อมีความหมาย)
หลังจากทั้งหมดนี้ตัวประมวลผลล่วงหน้าสร้างเอาต์พุตเดียวที่เป็นสตรีมของโทเค็นที่เป็นผลมาจากการแปลงที่อธิบายข้างต้น นอกจากนี้ยังเพิ่มเครื่องหมายพิเศษบางอย่างที่บอกคอมไพเลอร์ว่าแต่ละบรรทัดมาจากไหนเพื่อให้สามารถใช้ข้อความเหล่านั้นเพื่อสร้างข้อความแสดงข้อผิดพลาดที่สมเหตุสมผล
ข้อผิดพลาดบางอย่างสามารถเกิดขึ้นได้ในขั้นตอนนี้ด้วยการใช้คำสั่ง#if
และ#error
คำสั่งอย่างชาญฉลาด
การรวบรวม
ขั้นตอนการรวบรวมจะดำเนินการในแต่ละเอาต์พุตของตัวประมวลผลล่วงหน้า คอมไพเลอร์แยกวิเคราะห์รหัสที่มาบริสุทธิ์ C ++ (ตอนนี้ไม่มีคำสั่ง preprocessor ใด ๆ ) และแปลงเป็นรหัสประกอบ จากนั้นเรียกใช้ back-end พื้นฐาน (แอสเซมเบลอร์ใน toolchain) ที่ประกอบรหัสนั้นลงในรหัสเครื่องที่สร้างไฟล์ไบนารีจริงในบางรูปแบบ (ELF, COFF, a.out, ... ) ไฟล์อ็อบเจ็กต์นี้มีโค้ดที่คอมไพล์แล้ว (ในรูปแบบไบนารี) ของสัญลักษณ์ที่กำหนดในอินพุต สัญลักษณ์ในอ็อบเจ็กต์ไฟล์ถูกอ้างอิงโดยชื่อ
ไฟล์อ็อบเจ็กต์สามารถอ้างถึงสัญลักษณ์ที่ไม่ได้กำหนดไว้ นี่เป็นกรณีเมื่อคุณใช้การประกาศและไม่ได้ให้คำจำกัดความใด ๆ คอมไพเลอร์ไม่ได้สนใจสิ่งนี้และจะสร้างไฟล์ออบเจ็กต์อย่างมีความสุขตราบเท่าที่ซอร์สโค้ดมีรูปแบบที่ดี
คอมไพเลอร์มักจะให้คุณหยุดการรวบรวม ณ จุดนี้ สิ่งนี้มีประโยชน์มากเพราะคุณสามารถรวบรวมไฟล์โค้ดแต่ละไฟล์แยกกันได้ ข้อได้เปรียบที่มีให้คือคุณไม่จำเป็นต้องคอมไพล์ทุกสิ่งใหม่หากคุณเปลี่ยนไฟล์เพียงไฟล์เดียว
ไฟล์อ็อบเจ็กต์ที่สร้างสามารถใส่ในไฟล์เก็บถาวรพิเศษที่เรียกว่าสแตติกไลบรารีเพื่อให้นำกลับมาใช้ใหม่ได้ง่ายขึ้นในภายหลัง
ในขั้นตอนนี้จะมีการรายงานข้อผิดพลาดของคอมไพเลอร์ "ปกติ" เช่นข้อผิดพลาดทางไวยากรณ์หรือข้อผิดพลาดในการแก้ปัญหาโอเวอร์โหลดที่ไม่ถูกต้อง
การเชื่อมโยง
ตัวลิงก์คือสิ่งที่สร้างเอาต์พุตการคอมไพล์สุดท้ายจากอ็อบเจ็กต์ไฟล์ที่คอมไพเลอร์สร้างขึ้น เอาต์พุตนี้สามารถเป็นไลบรารีแบบแบ่งใช้ (หรือแบบไดนามิก) (และแม้ว่าชื่อจะคล้ายกัน แต่ก็ไม่มีอะไรเหมือนกันกับไลบรารีแบบคงที่ที่กล่าวถึงก่อนหน้านี้) หรือไฟล์ที่เรียกใช้งานได้
มันเชื่อมโยงไฟล์วัตถุทั้งหมดโดยแทนที่การอ้างอิงถึงสัญลักษณ์ที่ไม่ได้กำหนดด้วยที่อยู่ที่ถูกต้อง สัญลักษณ์เหล่านี้แต่ละตัวสามารถกำหนดได้ในไฟล์วัตถุอื่นหรือในไลบรารี หากมีการกำหนดไว้ในไลบรารีอื่นนอกเหนือจากไลบรารีมาตรฐานคุณจะต้องบอก linker เกี่ยวกับพวกเขา
ในขั้นตอนนี้ข้อผิดพลาดที่พบบ่อยที่สุดจะหายไปคำจำกัดความหรือคำนิยามที่ซ้ำกัน ก่อนหน้านี้หมายถึงว่าไม่มีคำจำกัดความ (เช่นพวกเขาไม่ได้เขียน) หรือว่าวัตถุไฟล์หรือห้องสมุดที่พวกเขาอาศัยอยู่ไม่ได้รับการ linker ชัดเจนหลัง: สัญลักษณ์เดียวกันถูกกำหนดในสองไฟล์อ็อบเจ็กต์หรือไลบรารีที่แตกต่างกัน