fsh*_*ikh 5 c gcc struct compiler-optimization
在一个文件struct_test.c中我写道:
static struct x x;
Run Code Online (Sandbox Code Playgroud)
我用GCC编译(4.8.2,Ubuntu)
gcc -c -O0 struct_test.c
Run Code Online (Sandbox Code Playgroud)
我得到了可以理解的错误:
error: storage size of 'x' isn't known
Run Code Online (Sandbox Code Playgroud)
然后我重新编译,这次打开了优化
gcc -c -O struct_test.c
Run Code Online (Sandbox Code Playgroud)
并且编译文件时没有错误.
我可以理解为什么启用优化会删除错误,但有人可以帮助我获取实际的编译器选项,指示gcc忽略未定义的标记'x'吗?
当它出现在文件范围时,此代码:
static struct x x;
Run Code Online (Sandbox Code Playgroud)
声明x为类型的对象struct x并具有内部链接。该类型struct x不需要事先声明:
如果该形式的类型说明符
struct-or-union identifier出现在 [in a struct type statements] 之外,并且没有其他标识符作为标记的声明可见,则它声明不完整的结构或联合类型,并将标识符声明为该标记的标记类型。
(C99 6.7.2.3/8)
第一次在翻译单元中遇到时不完整的结构或联合类型仍然可以稍后在该翻译单元中完成:
未知内容的结构或联合类型是不完整类型。对于该类型的所有声明,它是通过稍后在同一范围内声明相同的结构或联合标记及其定义内容来完成的。
(C99 6.2.5/22)
C 通常区分“声明”和“定义”,“声明”指定对象的类型,“定义”既指定类型又导致存储被保留。在给定的翻译单元中,不是定义的声明可能具有在该单元内永远不会完成的不完整类型。
C99 第 6.9.2 节指定哪些文件范围对象声明是定义:
0。本节还规定“如果对象标识符的声明是暂定定义并且具有内部链接,则声明的类型不应是不完整类型。” 这适用于此处,但由于翻译单元中某一点不完整的类型可以通过稍后的声明来完成,因此它本质上不会使相关代码行无效。但是,它确实会使仅包含该行的翻译单元无效。
由于给出的代码作为完整的翻译单元违反了“不得”语言约束,因此它会产生未定义的行为。GCC 没有义务拒绝代码或产生任何类型的诊断,但允许执行其中之一或两者。事实证明,无论优化级别如何,如果打开or标志gcc,都会发出有关代码的警告。无论如何,明确否认它是验证代码标准合规性的工具。-Wall-pedanticgcc
然而,这种特殊的违规行为相对温和。因为该对象从未被引用,gcc所以可以假装它从未被声明过,而不会有错误或意外行为的风险。
(死代码消除)选项-fdce似乎是影响这一特定行为的选项。奇怪的是,虽然-fdce足以在优化级别抑制错误O0,-fno-dce但并不能在更高的优化级别将其恢复。