phö*_*hön 7 c++ one-definition-rule inline-functions language-lawyer translation-unit
在visual studio中,您可以为各个cpp文件设置不同的编译器选项.例如:在"代码生成"下,我们可以在调试模式下启用基本运行时检查.或者我们可以改变浮点模型(精确/严格/快速).这些只是一些例子.有很多不同的旗帜.
只要定义相同,就可以在程序中多次定义内联函数.我们将此函数放入标题中并将其包含在多个翻译单元中.现在,如果不同的cpp文件中的不同编译器选项导致该函数的编译代码略有不同,会发生什么?然后他们确实不同,我们有不确定的行为?你可以使函数静态(或将它放入一个未命名的命名空间)但是更进一步,直接在类中定义的每个成员函数都是隐式内联的.这意味着如果这些cpp文件共享相同的编译器标志,我们可能只包含不同cpp文件中的类.我无法想象这是真的,因为这基本上是容易出错.
我们在未定义行为的土地上真的那么快吗?还是编译器会处理这种情况?
就标准而言,命令行标志的每种组合都会将编译器转变为不同的实现。虽然实现能够使用其他实现生成的目标文件很有用,但标准没有强制要求它们这样做。
即使没有内联,也可以考虑在一个编译单元中使用以下函数:
char foo(void) { return 255; }
Run Code Online (Sandbox Code Playgroud)
以及另一个中的以下内容:
char foo(void);
int arr[128];
void bar(void)
{
int x=foo();
if (x >= 0 && x < 128)
arr[x]=1;
}
Run Code Online (Sandbox Code Playgroud)
如果char是两个编译单元中的有符号类型,则第二个单元中的值x将小于零(从而跳过数组分配)。如果它在两个单元中都是无符号类型,则它将大于 127(同样跳过赋值)。但是,如果一个编译单元使用有符号char而另一个编译单元使用无符号,并且如果实现期望在结果寄存器中返回值进行符号扩展或零扩展,则结果可能是编译器可能会确定不能x更大小于 127,即使它包含 255,或者它不能小于 0,即使它包含 -1。因此,生成的代码可能会访问arr[255]or arr[-1],从而带来潜在的灾难性结果。
虽然在许多情况下使用不同编译器标志组合代码应该是安全的,但该标准没有努力区分这种混合是安全的和不安全的。
| 归档时间: |
|
| 查看次数: |
429 次 |
| 最近记录: |