Что такое «единица перевода» в 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.