【发布时间】:2019-02-02 16:16:47
【问题描述】:
在 Visual Studio 中,您可以为各个 cpp 文件设置不同的编译器选项。例如:在“代码生成”下,我们可以在调试模式下启用基本运行时检查。或者我们可以改变浮点模型(精确/严格/快速)。这些只是例子。有很多不同的标志。
一个内联函数可以在程序中定义多次,只要定义相同。我们把这个函数放在一个标题中,并将它包含在几个翻译单元中。现在,如果不同 cpp 文件中的不同编译器选项导致函数的编译代码略有不同,会发生什么情况?那么它们确实不同,我们有未定义的行为?您可以将函数设为静态(或将其放入未命名的命名空间),但更进一步,直接在类中定义的每个成员函数都是隐式内联的。这意味着如果这些 cpp 文件共享相同的编译器标志,我们只能在不同的 cpp 文件中包含类。我无法想象这是真的,因为这基本上很容易出错。
在未定义行为的土地上,我们真的那么快吗?还是编译器会处理这种情况?
【问题讨论】:
-
所以,
sum(2,2)在一个编译单元中给出 4,在另一个编译单元中给出 5。我在这里看不到未定义的行为, -
@AlexF 问题是the one definition rule。不同translation units 中的多个(不同)定义是UB。模板的情况略有不同,但对于非模板化的内联函数,它可能绝对是个问题。
-
@AlexF 它说必须在使用 odr 的每个翻译单元中定义内联函数,并且定义必须满足项目符号列表中的条件(这实际上是说所有定义必须看起来相同且等价)。
-
我认为这是一个灰色地带。 ODR 要求涉及多个定义的形式和语义,而不是生成的代码。
-
@Someprogrammerdude 我看不出如何用任何标准解释来解决这个问题,因为就语言而言,编译器标志甚至不存在。
标签: c++ language-lawyer one-definition-rule inline-functions translation-unit