【问题标题】:Microsoft C deviation from standard [duplicate]Microsoft C与标准的偏差[重复]
【发布时间】:2014-09-16 09:51:46
【问题描述】:

以下异常有什么原因吗?

考虑以下 C 程序(名为 PstFixInc.c)

#include <stdio.h>
int main (int argc, char *argv [])
{
  int num = 0;
  num = (num++) % 4;
  printf ("num: %d\n",num);
  return 0;
}

如果用gcc 4.8.1编译:

gcc -o PstFix.exe PstFixInc.c

然后执行,得到结果:

数量:0

如果使用 Microsoft (R) C/C++ Optimizing Compiler Version 18.00.21005.1 for x86 编译

cl PstFixInc.c

然后执行,得到结果:

数量:1

【问题讨论】:

  • 它取决于编译器!
  • num = (num++) % 4; 具有未定义的行为。见stackoverflow.com/a/4176333/12711
  • 这个问题经常被问到——查看“序列点”以获取更多信息。基本上,不,两个编译器都是正确的,是的,你的代码坏了。

标签: c gcc visual-studio-2013 undefined-behavior sequence-points


【解决方案1】:

这是未定义的行为。

您在没有交错 sequence point 的情况下将两次分配给同一个变量。

【讨论】:

    【解决方案2】:

    这一行:

    num = (num++) % 4;
    

    是 C 标准中未定义的行为。代码产生的任何结果都是“正确的”。

    【讨论】:

      【解决方案3】:

      您所拥有的是未定义的行为,您正在修改 num 并使用其先前的值来确定要存储在同一序列点内的值。这在草案 C99 标准部分 6.5 第 2 段中有所介绍:

      在上一个序列点和下一个序列点之间,对象的存储值最多只能通过评估 表达式.72) 此外,先验值应只读为 确定要存储的值。73)

      还有两个未定义行为的例子:

      i = ++i + 1;
      a[i++] = i;
      

      第一个与您的示例非常相似。 使用clang 甚至会给你一个很好的警告:

       warning: multiple unsequenced modifications to 'num' [-Wunsequenced]
        num = (num++) % 4;
        ~     ^
      

      【讨论】:

      • 看来改进的直接引用源代码的诊断是 clang(与 GCC 相比)的主要优势之一。
      猜你喜欢
      • 1970-01-01
      • 2013-08-05
      • 2013-06-20
      • 2015-06-27
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      • 2021-10-16
      • 2014-05-09
      相关资源
      最近更新 更多