GCC优化标志问题
我对一些用gcc编译器编译的C代码有问题。所讨论的代码有一个枚举,其值在switch语句中用作配置对象的事例。相当标准的东西 当我使用GCC优化标志问题,c,gcc,enums,C,Gcc,Enums,我对一些用gcc编译器编译的C代码有问题。所讨论的代码有一个枚举,其值在switch语句中用作配置对象的事例。相当标准的东西 当我使用-O0选项标记编译代码时,所有内容都正确构建和运行,没有问题。但是,当标志设置为-O2时,代码不再按预期工作 当我一步一步地浏览代码并观察局部变量时,enum(它应该只是三个enum值中的一个)实际上是-104!这会导致程序无法配置对象 以前有没有人遇到过这种情况,谁能提供一些指导?我以前从未遇到过这种情况,如果有人能解释编译器为什么会这样做,我将不胜感激,这样我
-O0
选项标记编译代码时,所有内容都正确构建和运行,没有问题。但是,当标志设置为-O2
时,代码不再按预期工作
当我一步一步地浏览代码并观察局部变量时,enum(它应该只是三个enum值中的一个)实际上是-104!这会导致程序无法配置对象
以前有没有人遇到过这种情况,谁能提供一些指导?我以前从未遇到过这种情况,如果有人能解释编译器为什么会这样做,我将不胜感激,这样我就可以进行任何必要的更改
有问题的代码片段:
value = 0u;
switch(test_config) {
case DISABLE:
break;
case INTERNAL:
value = 1u;
break;
case EXTERNAL:
value = 2u;
break;
default:
valid = FALSE;
break;
}
if (valid) {
configure_test(value);
}
typedef enum {
DISABLE,
INTERNAL,
EXTERNAL
} test_config_t;
有关枚举:
value = 0u;
switch(test_config) {
case DISABLE:
break;
case INTERNAL:
value = 1u;
break;
case EXTERNAL:
value = 2u;
break;
default:
valid = FALSE;
break;
}
if (valid) {
configure_test(value);
}
typedef enum {
DISABLE,
INTERNAL,
EXTERNAL
} test_config_t;
这是导致问题的代码。我最初没有包括它,因为我不希望问题是请修复我的代码,而是我一直在用谷歌搜索为什么gcc优化标志会对同一段代码产生不同的结果,并且没有发现任何特别有用的东西。另外,我不在电脑前,不得不在手机上输入,这也没用。所以我来到这里,是因为这里有比我更了解的专家可以为我指明正确的方向
我可能应该包括更多的信息。代码在硬件上运行,这可能也是问题所在,我也在研究这个问题。当从FSBL运行时,代码使用-O0,但不使用-O2。因此,它可能是硬件,但我不知道为什么它以一种方式而不是另一种方式工作。您没有提供足够的详细信息(因为您的问题没有显示任何实际的代码,它应该有一些),但您很可能有一些,您应该有 记住,or(像大多数一样)是由一个用英语编写的明确规范(不仅仅是代码中观察到的具体行为)定义的,并且部分定义了有效C程序的运行时行为。阅读 我强烈建议在接触或编译源代码之前阅读Lattner的博客 我建议至少使用(几乎)所有警告和调试信息进行编译,例如使用
gcc-Wall-Wextra-g
,然后改进代码以不获取警告,并在gdb
调试器下运行。阅读更多关于。您还可以(暂时)使用一些消毒剂,特别是-fsanitize=undefined
和-fsanitize=address
。您还可以将-std=gnu99
和-pedantic
添加到编译器标志中。请注意,gdb
是一个非常有用的调试器功能,用于查找值更改或意外的原因
当您编译用于发布或启用优化的基准测试时,也要保留警告标志(因此使用gcc-O2-Wall-Wextra
编译);优化可能会给出额外的警告,您也应该纠正这些警告。顺便说一句,同时接受-O2
和-g
当您观察到这些问题时,在怀疑编译器之前,请先询问您自己的代码
(因为编译器经过了很好的测试;我在近40年的编程中只发现了一个编译器错误)。您可以发布您的代码吗?是的,使用优化选项时,包含错误语句/未定义行为的代码可能会中断。不要发布代码,而是发布一个。绝对是UB。但是我们无中生有地不知道为什么。问题不在于你在上一版中展示的代码。它可能是在它的呼叫者!这不是一个。你还需要
-pedantic
和一些-std
选项,例如-std=gnu99
。你可能想使用GNU扩展,这是-pedantic
禁止的。-pedantic
不禁止GNU扩展。@melpomene:这不是文档所说的,我的措词太草率了。这取决于“禁止”和“GNU扩展”的含义(例如说“-pedantic
和其他选项会对许多GNU C扩展产生警告”,即不会对所有扩展发出警告,只是对很多扩展发出警告)。