2016-12-21 5 views
2

При использовании __DATE__ или __TIME__ в файле заголовка результаты препроцессора для включения этого заголовка могут быть несколько разными.Использует ли `__DATE__` или` __TIME__` нарушение правила единого определения?

В каких обстоятельствах использование __DATE__ или __TIME__ в файле заголовка нарушает правило с одним определением?

В качестве продолжения: заголовок assert нарушает правило с одним определением?

ответ

4

Если __TIME__ дает разные результаты для разных единиц перевода, то он не должен использоваться в контексте, где одинаковый результат требуется для единиц перевода. Это означает, например, инициализация объекта (например, члена класса) до __TIME__, где этот инициализатор является частью заголовка, который входит в множество единиц перевода, будет проблематичным.

__DATE__ имеет меньше шансов дать разные результаты для разных единиц перевода, если вы начинаете новую сборку, но инкрементные сборки, которые только перекомпилируют измененные файлы, также делают ее вероятной проблемой.

assert макрос, который расширяется по-разному в зависимости от того, как NDEBUG был определен, когда его заголовок был включен, так как весь проект должен договориться о том, следует ли определить NDEBUG, или функции, определенные в заголовках следует избегать использования assert.

0

Одно правило определения применимо только к переменным, функциям, типам классов, перечислениям или шаблонам (например, Раздел 3.2, ISO/IEC 14882, 1998 C++ Standard). __DATE__ или __TIME__ являются предопределенными макросами, которые расширяются до строкового литерала, что не является одним из условий, к которым применимо правило единого определения.

assert() также является макросом препроцессора. Если его расширение определяет переменную, функцию, тип класса, перечисление или шаблон, то его использование может потенциально нарушить правило одного определения, если это определение отличается между единицами перевода. Прагматично трудно предусмотреть ситуацию, при которой реализация будет иметь макрос assert(), который будет расширен до такого определения.