"หน่วยการแปล" ใน C ++ คืออะไร


236

ฉันกำลังอ่าน "C ++ ที่มีประสิทธิภาพ" ที่เขียนโดย Meyers และเจอคำว่า "หน่วยการแปล"

ใครช่วยกรุณาให้คำอธิบายของฉัน:

1) มันคืออะไรกันแน่

2) ฉันควรพิจารณาใช้เมื่อเขียนโปรแกรมด้วย C ++

3) ถ้ามันเกี่ยวข้องกับ C ++ เท่านั้นหรือสามารถใช้กับภาษาโปรแกรมอื่นได้

ฉันอาจใช้แล้วโดยไม่ทราบคำศัพท์ ....


1
2. คุณกำลังใช้หน่วยการแปลอยู่แล้วหากคุณรวมไฟล์ส่วนหัว มันเป็นคำที่ใช้สำหรับการอ้างอิงและไม่ใช่ c ++ สร้างต่อคำพูด
talekeDskobeDa

คำตอบ:


268

จากที่นี่ : ( ลิงก์เครื่อง wayback )

ตามมาตรฐาน C ++ ( ลิงก์เครื่องเวย์แบ็ก ): หน่วยแปลเป็นหน่วยพื้นฐานของการคอมไพล์ใน C ++ มันประกอบด้วยเนื้อหาของไฟล์ต้นฉบับเดียวรวมถึงเนื้อหาของไฟล์ส่วนหัวใด ๆ โดยตรงหรือโดยอ้อมรวมลบเส้นเหล่านั้นที่ถูกละเว้นโดยใช้คำสั่งการประมวลผลเงื่อนไขตามเงื่อนไข

หน่วยการแปลเดียวสามารถรวบรวมเป็นวัตถุไฟล์ไลบรารีหรือโปรแกรมที่ปฏิบัติการได้

แนวคิดของหน่วยการแปลมักถูกกล่าวถึงในบริบทของกฎการกำหนดหนึ่งคำและเทมเพลต


9
คำนี้ใช้เฉพาะใน C / C ++ หรือไม่
dekuShrub

2
@dekuShrub ตามความเป็นจริงไม่ใช่ ตัวอย่างเช่นใน Rust หน่วยการแปลคือลังใน C ++ สิ่งเดียวกันจะถูกเรียกว่าเป็นไลบรารีทั้งหมด คำนี้เป็นสากล แต่แน่นอนเริ่มต้นด้วย C.
Sahsahae

การอ้างอิงใหม่ซึ่งระบุคร่าวๆว่าคำตอบนี้ระบุอะไร: en.wikipedia.org/wiki/Translation_unit_(programming)
Gabriel Staples

67

หน่วยการแปลนั้นใช้สำหรับทุก intents และวัตถุประสงค์ของไฟล์ (.c / .cpp) หลังจากเสร็จสิ้นรวมถึงไฟล์ส่วนหัวทั้งหมด

http://msdn.microsoft.com/en-us/library/bxss3ska%28VS.80%29.aspx


3
รวมถึงไฟล์ส่วนหัว คอมไพเลอร์ไฟล์ประมวลผลส่วนหัวแม้ว่าจะไม่มีการสร้างรหัสก็ตาม ดูความคิดเห็นผู้ประมวลผลล่วงหน้าของ JeffH คำจำกัดความ "ทุกสิ่งที่คอมไพเลอร์มองเห็น" เป็นคำที่ดี
Marco van de Voort

10
คุณสามารถรวบรวมไฟล์ที่ลงท้ายด้วย ".h" ได้ดี ชื่อไฟล์นั้นไม่สำคัญเลย เนื้อหาคือ หากเนื้อหาของ "foo.h" คือ "int main () {}" คุณสามารถรวบรวมได้
Johannes Schaub - litb

@LightnessRacesinOrbit: ใช่สิ่งที่ฉันพยายามที่จะพูดคือมันเป็นเรื่องแปลกที่จะรวบรวมส่วนหัวเป็น TU โดยตรงแทนที่จะรวบรวมโดยอ้อมใน TU ผ่านการรวม ลบความคิดเห็นแรกสำหรับการทำผิดธรรมดารักษาวินาทีเพื่อให้บริบทใหม่ของเรา
GManNickG

1
@GManNickG: แล้วไฟล์ ".h นั้นจะไม่ถูกป้อนเข้าสู่คอมไพเลอร์โดยตรง
Lightness Races ในวงโคจร

@ JohannesSchaub-litb ฉันคิดว่าคุณหมายถึงลิงก์ไม่ใช่การคอมไพล์ คุณสามารถรวบรวมไฟล์ใดก็ได้ตราบใดที่มันเป็น C / C ++ ที่เหมาะสมกับชื่อทั้งหมดที่กำหนดไว้ มันจะไม่มีประโยชน์ในการรวบรวมไฟล์ส่วนหัวเนื่องจากจุดทั้งหมดของไฟล์ส่วนหัวจะรวมอยู่ (อ่านคัดลอก) ลงในไฟล์ต้นฉบับดังนั้นพวกเขาจะถูกรวบรวมแล้วเมื่อคุณรวบรวมไฟล์ต้นฉบับที่มี ฉันเดาว่าคุณหมายถึงอะไรคือคุณไม่สามารถสร้างไฟล์ที่เรียกใช้งานได้ซึ่งไม่มีฟังก์ชั่นหลัก
pooya13

30

คำถามยากที่จะตอบอย่างชัดเจน สถานะมาตรฐาน C ++:

ข้อความของโปรแกรมถูกเก็บไว้ในหน่วยที่เรียกว่าไฟล์ต้นฉบับในมาตรฐานสากลนี้ ไฟล์ต้นฉบับพร้อมกับส่วนหัวทั้งหมด (17.4.1.2) และไฟล์ต้นฉบับรวมอยู่ (16.2) ผ่านคำสั่ง preprocessing #include น้อยกว่าบรรทัดต้นฉบับที่ข้ามโดยคำสั่งการประมวลผลแบบมีเงื่อนไขใด ๆ (16.1) เรียกว่าหน่วยการแปล [หมายเหตุ: โปรแกรม C ++ ไม่จำเป็นต้องแปลทั้งหมดในเวลาเดียวกัน ]

ดังนั้นสำหรับจุดประสงค์และจุดประสงค์ส่วนใหญ่หน่วยการแปลคือไฟล์ต้นฉบับ C ++ ไฟล์เดียวและส่วนหัวหรือไฟล์อื่น ๆ จะรวมไว้ผ่านทางตัวประมวลผล #include

เกี่ยวกับคำถามอื่น ๆ ของคุณ:

2) ฉันควรพิจารณาใช้เมื่อเขียนโปรแกรมด้วย C ++

คุณไม่สามารถพิจารณาได้ - หน่วยการแปลเป็นพื้นฐานของโปรแกรม C ++

3) ถ้ามันเกี่ยวข้องกับ C ++ เท่านั้นหรือสามารถใช้กับภาษาโปรแกรมอื่นได้

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


1
ฉันไม่รู้ว่าจะชี้แจงหรือไม่ นี่อาจเป็นพื้นที่ที่ค่อนข้างมืด - มันไม่ชัดเจนจากพารามาตรฐานที่ฉันยกมาจากส่วนหัวที่คอมไพล์แล้วที่ได้รับอนุญาตตัวอย่างเช่น

1
@GMan และนั่นคือสิ่งที่คุณต้องระวังให้มากเกี่ยวกับกฎนิยามเดียว หากคุณรวมคลาสในหน่วยการแปลที่แตกต่างกันด้วยการกำหนดแตกต่างกันเล็กน้อยก่อนที่จะรวมคลาสนั้นทำให้คลาสมีรหัสที่แตกต่างกันมันจะทำให้เกิดปัญหาที่ไม่ได้กำหนด
ราคาแมตต์

6
@GMan บันทึกคำศัพท์สองคำที่ใช้โดย Standard: "header" และ "source file" "header" ใช้สำหรับไลบรารี่มาตรฐานเท่านั้น ไฟล์ผู้ใช้ที่รวมอยู่ในรหัสบางอย่างไม่ได้เรียกว่า "header" โดย Standard แต่เป็น "source file" มาตรฐานไม่ทราบเกี่ยวกับความแตกต่างระหว่าง ".h" และ ".cpp" ที่เรายากจน C ++ โปรแกรมเมอร์ทำขึ้น :)
โยฮันเน Schaub - litb

8

หนังสือทำให้ชัดเจน เมื่อเมเยอร์สอ้างถึง "หน่วยการแปล" เขาหมายถึงไฟล์ซอร์สโค้ด


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

3
@ ด่าน: ไม่มันไม่ใช่ หน่วยการแปลคือไฟล์ต้นฉบับหลังจากรวมไฟล์ซึ่งสามารถรวบรวมได้เช่นเอาท์พุทของตัวประมวลผลล่วงหน้าก่อนการรวบรวม
Ed S.

1
ในความเป็นจริงแม้จะมีสิ่งที่มาตรฐาน C ++ เรียกว่า "หน่วยการแปล" ทั่วไปที่ใช้ในการสื่อสารความคิดของ "หน่วย" เดียวของรหัสที่รวบรวม ในความเป็นจริงตาม Microsoft คอมไพเลอร์พวกคุณเชื่อมโยง "หน่วยการแปล" โดยตรง msdn.microsoft.com/en-us/library/vstudio/...
แดน

1
ดังนั้นเรากำลังพยายามที่จะเป็น "มาตรฐาน C ++" นาซีหรือเราพยายามที่จะช่วยให้ผู้คนสื่อสารกับส่วนที่เหลือของอุตสาหกรรม? ฉันรู้ว่านี่เป็นเธรด C ++ ดังนั้นฉันจึงไม่เข้าไปในสิ่งที่ xcode เรียกว่า tu หรือคำจำกัดความอื่น ๆ ทั้งหมดของคำ
ด่าน

1
@Dan: หน่วยการแปลคือสิ่งที่มาตรฐานเรียกว่า ฉันไม่ได้เกี่ยวข้องกับความคิดเห็นของผู้รวบรวม devs แบบสุ่มจริงๆ ที่น่าสนใจว่าคนที่ขุดเสานิพพานเกือบห้าปีและบอกฉันว่าคำจำกัดความของฉันผิดไปรอบ ๆ และเรียกฉันว่า "นาซีภาษา" สำหรับการแก้ไขของเขา ใช่เลยคุณกำลังเบื่อที่จะรับมือกับมัน
Ed S.

4

นอกจาก ODR แล้วหน่วยการแปลยังมีความสำคัญในคำจำกัดความของเนมสเปซที่ไม่มีชื่อซึ่งจะแทนที่การใช้ "static" แบบเก่าอย่างใดอย่างหนึ่ง

ฉันเดาว่าฉันยังมีคะแนนไม่พอที่จะเพิ่มความคิดเห็นภายใต้คำตอบยอดนิยม


3

หน่วยการแปลคือรหัสที่ส่งผ่านไปยังคอมไพเลอร์ที่เหมาะสม ซึ่งโดยทั่วไปจะหมายถึงเอาต์พุตจากการรันตัวประมวลผลล่วงหน้าบนไฟล์. c


2

โปรแกรม C และ C ++ ประกอบด้วยไฟล์ต้นฉบับหนึ่งไฟล์หรือมากกว่าซึ่งแต่ละไฟล์มีข้อความบางส่วนของโปรแกรม ไฟล์ต้นฉบับพร้อมกับไฟล์รวม (ไฟล์ที่รวมอยู่โดยใช้คำสั่ง #include preprocessor) แต่ไม่รวมส่วนของโค้ดที่ลบออกโดยคำสั่งการรวบรวมตามเงื่อนไขเช่น #if เรียกว่า "หน่วยการแปล"


1

ตามโปรแกรมMSDN : C และ C ++ ประกอบด้วยไฟล์ต้นฉบับหนึ่งไฟล์หรือมากกว่าซึ่งแต่ละไฟล์มีข้อความบางส่วนของโปรแกรม ไฟล์ต้นฉบับพร้อมกับไฟล์รวม (ไฟล์ที่รวมอยู่โดยใช้คำสั่ง #include preprocessor) แต่ไม่รวมส่วนของโค้ดที่ลบออกโดยคำสั่งการรวบรวมตามเงื่อนไขเช่น #if เรียกว่า "หน่วยการแปล"


0

ไฟล์ cpp / c (การนำไปใช้) ทุกไฟล์จะถูกแปลงเป็นหน่วยการแปล (เช่น. object file (.obj)) ส่วนหัวในไฟล์ cpp จะถูกแทนที่ด้วยข้อความจริงจากไฟล์ส่วนหัว


0

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


1
"คุณจะต้องกังวลเกี่ยวกับมันหากคุณเขียนคอมไพเลอร์ C หรือ C ++" ฉันไม่เห็นด้วย: โปรแกรมเมอร์มักจะต้องเข้าใจสิ่งที่คอมไพเลอร์กำลังทำอยู่ ตัวอย่างเช่นคุณจำเป็นต้องรู้ว่าหน่วยการแปลคืออะไรเพื่อให้เข้าใจจุดสำคัญจากรายการ # 5 ใน Effective C ++: "ลำดับที่สัมพันธ์กันของการเริ่มต้นของวัตถุคงที่ที่ไม่ใช่ของท้องถิ่นที่กำหนดไว้ในหน่วยการแปลที่แตกต่างกัน
Channing Moore

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