编译器反转C行顺序?

时间:2015-12-03 12:33:22

标签: c stdio

我有这个示例代码:

ErrorType

你可以看到printf在gets(s)之前,但是当我运行代码时,它会在打印数字后首先询问字符串。我正在使用NetBeans和Cygwin gcc编译器。有什么我想念的吗?这是编译器错误吗?

1 个答案:

答案 0 :(得分:12)

printf()通常是行缓冲的。因此,在刷新缓冲区之前,printf的输出不会出现在屏幕上。

\n添加到printf,它应该按预期工作。

printf("%d\n",x);

如果使用setbuf(stdout, NULL);,则可以禁用缓冲。

顺便说一下,你永远不应该gets()。请改用fgets()。因为gets()容易出现缓冲区溢出漏洞,并且自C99以来已被淘汰,并且已从C11中完全删除。

关于您怀疑编译器正在重新排序这些行:编译器可以重新排序指令,并且允许合法地执行此操作。 但只要它不影响程序的可观察效果

考虑以下代码,

void func(void)
{
   int a = 2;
   int b = 3;

   a = a * 2;  //line 1
   b = b + 3;  //line 2

   printf("%d\n", a+b);
}

编译器可以按任何顺序(line1或line2)计算ab,因为它不会影响代码的行为。或者它甚至可以简单地用以下函数替换函数:

void func(void)
{
   printf("%d\n", 10);
}

通常,编译器会进行此类转换以进行优化,并且是允许的。在您的代码中,编译器不能执行此类代码转换,因为它会影响代码的可观察行为。