นี่อาจเป็นคำตอบที่ละเอียดกว่าที่คุณต้องการ แต่ฉันคิดว่าคำอธิบายที่เหมาะสมเป็นสิ่งที่ถูกต้อง
ใน C และ C ++ ไฟล์ต้นฉบับหนึ่งไฟล์จะถูกกำหนดเป็นหนึ่งหน่วยการแปลหน่วยการแปลตามแบบแผนไฟล์ส่วนหัวจะมีการประกาศฟังก์ชั่นคำจำกัดความประเภทและคำจำกัดความของคลาส การใช้งานฟังก์ชั่นที่แท้จริงอยู่ในหน่วยการแปลเช่นไฟล์. cpp
แนวคิดเบื้องหลังนี้คือฟังก์ชั่นและฟังก์ชั่นสมาชิกคลาส / โครงสร้างจะรวบรวมและประกอบหนึ่งครั้งจากนั้นฟังก์ชั่นอื่น ๆ สามารถเรียกรหัสนั้นจากที่เดียวโดยไม่ต้องทำซ้ำ ฟังก์ชั่นของคุณถูกประกาศเป็น "ภายนอก" โดยปริยาย
/* Function declaration, usually found in headers. */
/* Implicitly 'extern', i.e the symbol is visible everywhere, not just locally.*/
int add(int, int);
/* function body, or function definition. */
int add(int a, int b)
{
return a + b;
}
หากคุณต้องการให้ฟังก์ชั่นเป็นท้องถิ่นสำหรับหน่วยการแปลคุณกำหนดมันเป็น 'คงที่' สิ่งนี้หมายความว่า? หมายความว่าหากคุณรวมไฟล์ต้นฉบับด้วยฟังก์ชั่น extern คุณจะได้รับข้อผิดพลาดในการกำหนดซ้ำเนื่องจากคอมไพเลอร์เจอการใช้งานเดียวกันมากกว่าหนึ่งครั้ง ดังนั้นคุณต้องการให้หน่วยการแปลทั้งหมดของคุณเห็นการประกาศฟังก์ชันแต่ไม่ใช่เนื้อหาของฟังก์ชันร่างกายทำงาน
ดังนั้นในตอนท้ายมันจะถูกบดเข้าด้วยกันอย่างไร? นั่นคืองานของลิงเกอร์ ตัวเชื่อมโยงจะอ่านไฟล์วัตถุทั้งหมดที่สร้างขึ้นโดยแอสเซมเบลอร์แอสเซมเบลอร์และแก้ไขสัญลักษณ์ อย่างที่ฉันพูดไปแล้วสัญลักษณ์เป็นเพียงชื่อ ตัวอย่างเช่นชื่อของตัวแปรหรือฟังก์ชั่น เมื่อหน่วยการแปลที่เรียกใช้ฟังก์ชั่นหรือประกาศประเภทไม่ทราบว่าการใช้งานสำหรับฟังก์ชั่นหรือประเภทเหล่านั้นสัญลักษณ์เหล่านั้นจะถูกกล่าวว่าไม่ได้รับการแก้ไข ตัวเชื่อมโยงจะแก้ไขสัญลักษณ์ที่ไม่ได้แก้ไขโดยเชื่อมต่อหน่วยการแปลซึ่งมีสัญลักษณ์ที่ไม่ได้กำหนดพร้อมกับที่มีการใช้งาน วุ้ย. สิ่งนี้เป็นจริงสำหรับสัญลักษณ์ที่มองเห็นจากภายนอกทั้งหมดไม่ว่าจะถูกนำไปใช้ในโค้ดของคุณหรือจัดหาโดยไลบรารีเพิ่มเติม ไลบรารีเป็นเพียงไฟล์เก็บถาวรที่มีรหัสที่สามารถใช้ซ้ำได้
มีข้อยกเว้นเด่นสองประการ ขั้นแรกหากคุณมีฟังก์ชั่นขนาดเล็กคุณสามารถทำให้มันเป็นแบบอินไลน์ ซึ่งหมายความว่ารหัสเครื่องที่สร้างขึ้นไม่ได้สร้างการเรียกใช้ฟังก์ชัน extern แต่จะถูกรวมเข้าด้วยกันอย่างแท้จริง เนื่องจากโดยปกติแล้วจะมีขนาดเล็กค่าใช้จ่ายขนาดจึงไม่สำคัญ คุณสามารถจินตนาการให้พวกเขาคงที่ในวิธีที่พวกเขาทำงาน ดังนั้นจึงปลอดภัยที่จะใช้ฟังก์ชั่นอินไลน์ในส่วนหัว การใช้งานฟังก์ชั่นภายในคำจำกัดความคลาสหรือ struct ก็มักจะ inline โดยอัตโนมัติโดยคอมไพเลอร์
ข้อยกเว้นอื่น ๆ คือแม่แบบ เนื่องจากคอมไพเลอร์จำเป็นต้องเห็นคำจำกัดความชนิดเทมเพลตทั้งหมดเมื่อสร้างอินสแตนซ์ให้กับอินสแตนซ์จึงไม่สามารถแยกการใช้งานจากข้อกำหนดเช่นเดียวกับฟังก์ชันสแตนด์อโลนหรือคลาสปกติ บางทีอาจเป็นไปได้ในตอนนี้ แต่การได้รับการสนับสนุนคอมไพเลอร์อย่างกว้างขวางสำหรับคำหลัก "ส่งออก" ใช้เวลานานนาน ดังนั้นหากไม่มีการสนับสนุนสำหรับ 'ส่งออก' หน่วยการแปลจะได้รับสำเนาของตัวเองในประเภทของเทมเพลตและฟังก์ชันที่สร้างอินสแตนซ์เทมเพลตซึ่งคล้ายกับการทำงานของอินไลน์ ด้วยการสนับสนุนสำหรับ 'ส่งออก' นี่ไม่ใช่กรณี
สำหรับทั้งสองข้อยกเว้นบางคนพบว่า "ดีกว่า" เพื่อนำการใช้งานของฟังก์ชั่นอินไลน์, ฟังก์ชั่น templated และประเภท templated ในไฟล์. cpp แล้ว #include ไฟล์. cpp ไม่ว่าจะเป็นส่วนหัวหรือไฟล์ต้นฉบับไม่สำคัญ ตัวประมวลผลล่วงหน้าไม่สนใจและเป็นเพียงแบบแผน
ข้อมูลสรุปอย่างย่อของกระบวนการทั้งหมดจากรหัส C ++ (หลายไฟล์) และไปสู่การปฏิบัติการขั้นสุดท้าย:
- preprocessorจะดำเนินการซึ่งจะแยกวิเคราะห์คำสั่งทั้งหมดที่เริ่มต้นด้วย '#' คำสั่ง #include เชื่อมไฟล์ที่รวมเข้าด้วยกันให้เป็นรอง นอกจากนี้ยังทำการทดแทนมาโครและโทเค็นการวาง
- คอมไพเลอร์จริงรันบนไฟล์ข้อความระดับกลางหลังจากระยะตัวประมวลผลล่วงหน้าและปล่อยรหัสแอสเซมเบลอร์
- ประกอบวิ่งบนไฟล์ประกอบและส่งเสียงรหัสเครื่องนี้มักจะเรียกว่าไฟล์วัตถุและตามรูปแบบไบนารีของระบบการทำงานในคำถาม ตัวอย่างเช่น Windows ใช้ PE (รูปแบบที่ปฏิบัติการได้แบบพกพา) ในขณะที่ Linux ใช้รูปแบบ Unix System V ELF พร้อมส่วนขยาย GNU ในขั้นตอนนี้สัญลักษณ์ยังคงถูกทำเครื่องหมายว่าไม่ได้กำหนด
- ในที่สุดlinkerจะทำงาน ขั้นตอนก่อนหน้าทั้งหมดถูกเรียกใช้ในหน่วยการแปลแต่ละหน่วยตามลำดับ อย่างไรก็ตามตัวเชื่อมโยงสเตจทำงานกับไฟล์อ็อบเจ็กต์ทั้งหมดที่สร้างขึ้นซึ่งแอสเซมเบลอร์สร้างขึ้น ตัวเชื่อมโยงจะแก้ไขสัญลักษณ์และทำเวทมนต์มากมายเช่นการสร้างส่วนและเซกเมนต์ซึ่งขึ้นอยู่กับแพลตฟอร์มเป้าหมายและรูปแบบไบนารี โปรแกรมเมอร์ไม่จำเป็นต้องรู้สิ่งนี้โดยทั่วไป แต่ก็มีประโยชน์ในบางกรณี
นี่เป็นสิ่งที่มากกว่าที่คุณร้องขออย่างแน่นอน แต่ฉันหวังว่ารายละเอียดที่เป็นประโยชน์จะช่วยให้คุณเห็นภาพที่ใหญ่ขึ้น