【发布时间】:2016-12-21 08:18:00
【问题描述】:
在头文件中使用__DATE__ 或__TIME__ 时,包含该头文件的预处理器的结果可能会有所不同。
在什么情况下在头文件中使用__DATE__或__TIME__会违反单定义规则?
作为后续:assert 标头是否违反单一定义规则?
【问题讨论】:
标签: c++ datetime c-preprocessor one-definition-rule
在头文件中使用__DATE__ 或__TIME__ 时,包含该头文件的预处理器的结果可能会有所不同。
在什么情况下在头文件中使用__DATE__或__TIME__会违反单定义规则?
作为后续:assert 标头是否违反单一定义规则?
【问题讨论】:
标签: c++ datetime c-preprocessor one-definition-rule
如果__TIME__ 为不同的翻译单元提供不同的结果,则不得在需要跨翻译单元获得相同结果的上下文中使用它。这意味着例如将对象(例如类成员)初始化为 __TIME__,其中该初始化程序是包含在多个翻译单元中的标头的一部分,将会有问题。
__DATE__ 如果您开始新构建,则不太可能为不同的翻译单元提供不同的结果,但增量构建(仅重新编译已更改的文件)确实也可能成为问题。
assert 是一个宏,其扩展方式取决于 NDEBUG 在包含其标头时的定义方式,因此整个项目必须就是否应定义 NDEBUG 达成一致,或者标头中定义的函数应避免使用assert.
【讨论】:
单一定义规则仅适用于变量、函数、类类型、枚举或模板(例如,第 3.2 节、ISO/IEC 14882、1998 C++ 标准)。 __DATE__ 或 __TIME__ 都是扩展为字符串文字的预定义宏 - 这不是单一定义规则适用的事物之一。
assert() 也是一个预处理器宏。如果它的扩展定义了一个变量、函数、类类型、枚举或模板,那么如果该定义在翻译单元之间不同,那么它的使用可能会违反单一定义规则。从实用的角度来看,很难想象一个实现会有一个扩展为这样一个定义的assert() 宏。
【讨论】: