误解C switch语句或gcc bug?

时间:2016-12-06 03:07:13

标签: c gcc switch-statement gcc5

使用时编译时,以下代码似乎正确执行 GCC 4.4.7和LLVM 6.1。但我不认为它正确编译gcc版本 5.4.0 20160609(Ubuntu 5.4.0-6ubuntu1~16.04.4)。

以下是我将问题简化为:

#include <stdio.h>
#include <stdlib.h>

#define GENERAL 1
#define BRACKETS 2
#define QUOTES 3

//This method contains the issue.
void foo(char *qb, char* into) {
  //The starting state is important for the bug.
  int state = QUOTES;
  int save_state = BRACKETS;

  //This here needs to reference qb in some way, previously I 
  //had this as just qb however I will set it to qb[0]. Note that this
  //is a contrived  example, I already know that setting it to one
  //makes this pass which makes me suspect this is a compiler 
  //issue.
  while (qb[0]) {
    printf("State is %d\n", state);
    switch (state) {
    case BRACKETS:
      printf("Yay this was correctly executed\n");
      exit(0);
      break;
    case GENERAL:
        printf("Oh no how did you get here?\n");
        printf("State is %d\n", state);
        exit(1);
      break;
    case QUOTES:
        state = save_state;
        printf("State went to %d btw BRACKETS is %d\n", state, BRACKETS);
        save_state = GENERAL; //Remove this line and it will work even
when optimised.
        printf("After save state, state went to %d btw BRACKETS is
%d\n", state, BRACKETS);
      break;
    default: ;
    }
    printf("State %d btw GENERAL %d\n", state, GENERAL);
  }
  printf("If you see this then something is really wrong.\n");
  exit(4);
}

int main() {
    //These don't seem to matter don't concern yourself with them.
    char *b = "123";
    char out[4];
    foo(b, out);
    return 1;
}

如果我用以下代码编译: gcc -O0 -g -Wall -Werror sillyswitch.c -o sillyswitch

会打印

Yay this was correctly executed

这是我希望它打印的内容

但是如果我用以下代码编译它: gcc -O -g -Wall -Werror sillyswitch.c -o sillyswitch

会打印

Oh no how did you get here?

这不是我期望看到的。

我不知道为什么在打开优化时它无法按预期工作。代码是错误的,因为在第二个循环上采用的switch语句的分支是任意的吗?因为它是C我以某种方式射击自己的脚?

完整输出失败:

State is 3
State went to 2 btw BRACKETS is 2
After save state, state went to 2 btw BRACKETS is 2
State 2 btw GENERAL 1
State is 2
Oh no how did you get here?
State is 1

成功完整输出:

State is 3
State went to 2 btw BRACKETS is 2
After save state, state went to 2 btw BRACKETS is 2
State 2 btw GENERAL 1
State is 2
Yay this was correctly executed

0 个答案:

没有答案