GCC优化标志问题

GCC优化标志问题,c,gcc,enums,C,Gcc,Enums,我对一些用gcc编译器编译的C代码有问题。所讨论的代码有一个枚举,其值在switch语句中用作配置对象的事例。相当标准的东西 当我使用-O0选项标记编译代码时,所有内容都正确构建和运行,没有问题。但是,当标志设置为-O2时,代码不再按预期工作 当我一步一步地浏览代码并观察局部变量时,enum(它应该只是三个enum值中的一个)实际上是-104!这会导致程序无法配置对象 以前有没有人遇到过这种情况,谁能提供一些指导?我以前从未遇到过这种情况,如果有人能解释编译器为什么会这样做,我将不胜感激,这样我

我对一些用gcc编译器编译的C代码有问题。所讨论的代码有一个枚举,其值在switch语句中用作配置对象的事例。相当标准的东西

当我使用
-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扩展产生警告”,即不会对所有扩展发出警告,只是对很多扩展发出警告)。