Що таке "одиниця перекладу" в C ++


236

Я читав у той час "Ефективний C ++", написаний Майєрсом, і натрапив на термін "перекладацька одиниця".

Чи можете мені хтось пояснити:

1) Що це саме

2) Коли я повинен розглянути можливість його використання при програмуванні на C ++

3) Якщо він пов'язаний лише з C ++, або його можна використовувати з іншими мовами програмування

Я, можливо, вже використовую його, не знаючи терміна ....


1
2. Ви вже використовуєте блок перекладу, якщо ви включили файли заголовка. Це термін, який використовується для посилання, а не конструкція c ++ за скажімо
talekeDskobeDa

Відповіді:


268

Від сюди : ( Вайбак машина посилання )

Відповідно до стандарту C ++ ( зворотний зв’язок машини ): Одиниця перекладу - це основна одиниця компіляції в C ++. Він складається із вмісту одного вихідного файлу, а також вмісту будь-яких файлів заголовків, які безпосередньо чи опосередковано входять до нього, за вирахуванням тих рядків, які були проігноровані за допомогою операторів умовної попередньої обробки.

Один блок перекладу може бути скомпільований у об’єктний файл, бібліотеку чи виконувану програму.

Поняття одиниці перекладу найчастіше згадується в контекстах Правил одного визначення та шаблонах.


9
Чи використовується термін лише в C / C ++?
dekuShrub

2
@dekuShrub, по суті, ні. Наприклад, у Rust перекладацька одиниця - це ящик, у C ++ те саме, що називалося б цілою бібліотекою. Сам термін є універсальним, але він, безумовно, почався з C.
Sahsahae

Нова посилання, в якій приблизно зазначено, що ця відповідь: en.wikipedia.org/wiki/Translation_unit_(programming)
Габріель Степлес

67

Одиниця перекладу - це всім намірам і цілям файлу (.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 () {}", ви можете скласти його.
Йоханнес Шауб - ліб

@LightnessRacesinOrbit: Так, те, що я намагався сказати, це те, що неортодоксально безпосередньо складати заголовок як TU, а не побічно компілювати його в TU через включення. Перший коментар видалено за те, що він явно помилявся, а другий залишав контекст для нових.
GManNickG

1
@GManNickG: Як щодо ".h файлів, як правило, не подаються безпосередньо до компілятора."
Гонки легкості на орбіті

@ JohannesSchaub-litb Я думаю, ви маєте на увазі посилання, а не компіляція. Ви можете компілювати будь-який файл, якщо це правильний C / C ++ з усіма визначеними іменами. Було б марно компілювати файл заголовка, оскільки вся точка заголовкового файлу повинна бути включена (прочитана скопійована) у вихідні файли, тому вони вже збираються, коли ви компілюєте вихідний файл, що включає його. Я думаю, що ви хотіли сказати, що ви не можете створити виконуваний файл з файлу, який не має основної функції.
pooya13

30

Важке питання остаточно відповісти. Стандарт C ++ визначає:

Текст програми зберігається в одиницях, що називаються вихідними файлами цього Міжнародного стандарту. Вихідний файл разом із усіма заголовками (17.4.1.2) та вихідними файлами (16.2) через директиву про попередню обробку #include, за вирахуванням будь-яких джерельних рядків, пропущених будь-якою з умов умовного включення (16.1) щодо попередньої обробки, називається одиницею перекладу. [Примітка: програму C ++ не потрібно переводити одночасно. ]

Отже, для більшості намірів і цілей перекладацький блок - це єдиний вихідний файл C ++, а заголовок або інші файли, які він включає через механізм препроцесора #include.

Щодо інших ваших питань:

2) Коли я повинен розглянути можливість його використання при програмуванні на C ++

Ви не можете це врахувати - одиниці перекладу є основою програми C ++.

3) Якщо він пов'язаний лише з C ++, або його можна використовувати з іншими мовами програмування

Інші мови мають подібні поняття, але їх семантика буде дещо різною. Більшість інших мов, наприклад, не використовують препроцесор.


1
Я не знаю, пояснює це чи ні. Це може бути дещо каламутна область - із стандартного пункту, який я цитував, не зрозуміло, що попередньо складені заголовки дозволені, наприклад.

1
@GMan, і тут потрібно бути дуже уважним щодо одного правила визначення. Якщо ви включите клас у різні підрозділи перекладу з дещо різними визначеннями до того, як цей клас буде включений, що призведе до того, що клас має інший код, це спричинить невизначені проблеми.
Метт Ціна

6
@GMan відзначте два терміни, які використовуються стандартом: "заголовок" та "вихідний файл". "заголовок" використовується лише для бібліотеки "Стандарт". Користувацький файл, включений у якийсь код, називається не стандартним "заголовком", а "вихідним файлом". Стандарт не знає про різницю між ".h" та ".cpp", яку ми складали бідні програмісти c ++ :)
Йоханнес Шауб - litb

8

Книга дає зрозуміти досить. Коли Мейєрс звертається до "Блок перекладу", він має на увазі файл вихідного коду.


1
Ні. Якщо він говорив про вихідний код, він сказав би вихідні файли. Блок перекладу виготовляється шляхом складання вихідного коду. Зверніть увагу на різну різницю. Це "Перекладений" вихідний код.
День

3
@Dan: Ні, це не так. Блок перекладу - це вихідний файл після включення, який може бути складений, тобто вихід препроцесора перед компіляцією.
Ред С.

1
Насправді, незважаючи на те, що називає його стандарт C ++, "одиниця перекладу" зазвичай використовується для передачі ідеї єдиного "Одиниці" складеного коду. Насправді, за словами хлопців-компіляторів Microsoft, ви безпосередньо посилаєтесь на "Одиниці перекладу". msdn.microsoft.com/en-us/library/vstudio / ...
Dan

1
Тож ми намагаємось бути нацистами "С ++" чи намагаємось допомагати людям спілкуватися з іншою частиною галузі? Я знаю, що це нитка C ++, тому я не хочу зайти в те, що xcode викликає ту. Або всі інші визначення терміна.
Дан

1
@Dan: Одиниця перекладу - це те, що стандарт називає. Я насправді не переймається думкою випадкових розробників компіляторів. Цікаво, що хлопець, який викопав майже п’ятирічну посаду до нітпіка і сказав мені, що моє визначення неправильне, обертається і називає мене "мовою нацисткою" для виправлення його. Так, рухайся далі, ти втомишся мати справу.
Ред С.

4

Окрім ODR, підрозділ перекладу важливий у визначенні неназваних просторів імен, що замінює одне із старих застосувань "статичного".

Напевно, у мене ще недостатньо балів, щоб додати коментар під головною відповіддю.


3

Одиниця перекладу - це код, який передається компілятору належним чином. Зазвичай це означає вихід із запуску препроцесора у файл .c.


2

Програми C і C ++ складаються з одного або декількох вихідних файлів, кожен з яких містить частину тексту програми. Вихідний файл разом із його файлами включають файли (файли, що входять із застосуванням директиви препроцесора #include), але не включаючи розділи коду, вилучені директивами умовної компіляції, такими як #if, називають "одиницею перекладу".


1

Згідно з MSDN : Програми C і C ++ складаються з одного або декількох вихідних файлів, кожен з яких містить частину тексту програми. Вихідний файл разом із його файлами включають файли (файли, що входять із застосуванням директиви препроцесора #include), але не включаючи розділи коду, вилучені директивами умовної компіляції, такими як #if, називають "одиницею перекладу".


0

Кожен файл cpp / c (реалізації) буде перетворений в блок перекладу (тобто, заголовки об'єктного файлу (.obj)) у файлі cpp, буде замінено фактичним текстом із файлів заголовка.


0

Як говорили інші, блок перекладу - це в основному вміст вихідного файлу після попередньої обробки. Це найвище виробництво в граматиці мови; вам потрібно буде турбуватися про це, лише якщо ви писали компілятор C або C ++.


1
"вам потрібно буде турбуватися про це, лише якщо ви пишете компілятор C або C ++." Я не згоден: програмістам часто потрібно зрозуміти, що робить компілятор. Так, наприклад, вам потрібно знати, що таке одиниця перекладу, щоб зрозуміти важливий пункт із пункту №5 в Ефективній C ++: "відносний порядок ініціалізації не локальних статичних об'єктів, визначених у різних одиницях перекладу, не визначений".
Ченнінг Мур

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.