C 编译器在表达式中的 pre/post 递增求值
C compiler's pre/post incrementation evaluation in expressions
今天我发现了一些东西,这让我对我的 C++ 或基本编程技能感到非常焦虑。问题是 post/pre 递增的 C++ 表达式求值。
让我们检查一下,让我说一下,简单的代码示例:
int a = 5;
int d = a++ + a;
正如我所料,'='符号的左右操作数将被独立计算,最终结果是(a++) 5 + (a) 5,其中post-incremented 'a' 在计算 'd' 后的值为 6。
但是,这是我在两个流行的 C 编译器下得到的结果:
MinGW: d == 11;
MSVC: d == 10;
同样的情况是:
int a = 5;
int d = a-- + a;
编译器给出的位置:
MinGW: d == 9; // 5 + 4 , a=4 after 'a--', before '+a'?
MSVC: d == 10; // 5 + 5 , a=4 after 'a-- + a'?
MSVC 输出与我预期的完全一样。问题是这里到底发生了什么?哪个编译器更接近定义为标准的行为?
有趣的是你应该问 "behaviour defined as standard";事实上,两个编译器都完全符合标准,因为您的程序调用了 undefined behavior.
简而言之,+
的操作数(以及大多数其他二元运算符)相对于彼此 未排序 :它们可以按任一顺序求值,并且根据特定顺序(通过副作用)调用未定义的行为。
当然,对于未定义的行为,符合标准的编译器可以选择合法地做任何事情。
C++ 标准未指定表达式 a++ + a
的执行顺序,因此每个编译器都可以根据需要自由计算表达式。由于两个编译器都是正确的,您需要将表达式重写为两个单独的语句以获得您想要的特定行为。
今天我发现了一些东西,这让我对我的 C++ 或基本编程技能感到非常焦虑。问题是 post/pre 递增的 C++ 表达式求值。
让我们检查一下,让我说一下,简单的代码示例:
int a = 5;
int d = a++ + a;
正如我所料,'='符号的左右操作数将被独立计算,最终结果是(a++) 5 + (a) 5,其中post-incremented 'a' 在计算 'd' 后的值为 6。
但是,这是我在两个流行的 C 编译器下得到的结果:
MinGW: d == 11;
MSVC: d == 10;
同样的情况是:
int a = 5;
int d = a-- + a;
编译器给出的位置:
MinGW: d == 9; // 5 + 4 , a=4 after 'a--', before '+a'?
MSVC: d == 10; // 5 + 5 , a=4 after 'a-- + a'?
MSVC 输出与我预期的完全一样。问题是这里到底发生了什么?哪个编译器更接近定义为标准的行为?
有趣的是你应该问 "behaviour defined as standard";事实上,两个编译器都完全符合标准,因为您的程序调用了 undefined behavior.
简而言之,+
的操作数(以及大多数其他二元运算符)相对于彼此 未排序 :它们可以按任一顺序求值,并且根据特定顺序(通过副作用)调用未定义的行为。
当然,对于未定义的行为,符合标准的编译器可以选择合法地做任何事情。
C++ 标准未指定表达式 a++ + a
的执行顺序,因此每个编译器都可以根据需要自由计算表达式。由于两个编译器都是正确的,您需要将表达式重写为两个单独的语句以获得您想要的特定行为。