Что такое «единица перевода» в C ++


236

В то время я читал «Эффективный C ++», написанный Мейерсом и натолкнулся на термин «единица перевода».

Может ли кто-нибудь дать мне объяснение:

1) Что именно это

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

3) Если он связан только с C ++ или может использоваться с другими языками программирования

Я мог бы уже использовать его, не зная термина ....


1
2. Вы уже используете модуль перевода, если вы включили заголовочные файлы. Это термин, используемый для ссылки, а не конструкция С ++, скажем так
— 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
Включая заголовочные файлы. Заголовочные файлы обрабатываются компилятором, даже если код не генерируется. Смотрите также комментарий препроцессора Джеффа, определение «все, что видит компилятор» является хорошим.
— Марко ван де Воорт

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», которую мы, бедные программисты на С ++, придумали :)
— Йоханнес Шауб - litb

8

Книга проясняет это достаточно. Когда Мейерс ссылается на «модуль перевода», он имеет в виду файл исходного кода.


1
Нет. Если бы он говорил об исходном коде, он сказал бы исходные файлы. Единица перевода сделана путем компиляции исходного кода. Обратите внимание на четкую разницу. Это «переведенный» исходный код.
— Дан

3
@ Дан: Нет, это не так. Единицей перевода является исходный файл после включений, который может быть скомпилирован, т. Е. Выходные данные препроцессора перед компиляцией.
— Эд С.

1
На самом деле, несмотря на то, что стандарт C ++ называет это, «модуль перевода» обычно используется для передачи идеи единого «модуля» скомпилированного кода. На самом деле, по словам ребят из компилятора Microsoft, вы напрямую связываете «Единицы перевода». msdn.microsoft.com/en-us/library/vstudio/…
— Дан

1
Таким образом, мы пытаемся быть нацистами "стандарта C ++" или мы пытаемся помочь людям общаться с остальной частью отрасли? Я знаю, что это поток C ++, поэтому я не буду вдаваться в то, что xcode называет tu. Или все другие определения термина.
— Дан

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 ++: «Относительный порядок инициализации нелокальных статических объектов, определенных в разных единицах перевода, не определен».
— Ченнинг Мур

0

На мой взгляд, «единица перевода» обычно представляет собой один исходный файл «после предварительной обработки». Вы можете получить более подробную информацию на этой странице MSDN. http://msdn.microsoft.com/en-us/library/bxss3ska(v=vs.80).aspx

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.