提问人:Ángel 提问时间:10/8/2023 最后编辑:Jan SchultkeÁngel 更新时间:10/8/2023 访问量:128
使用 MSVC 编译器和 GCC 编译器时获得的结果不同
Different results obtained when using MSVC compiler and GCC compiler
问:
我有这个简单的小代码:
#include <iostream>
int Add (int x, int y) {
std::cout << "In Add(), received " <<x<< " and " <<y<< "\n";
return (x+y);
}
int main () {
std::cout << "In main ()\n";
std::cout << "\nCalling Add ()\n";
std::cout << "value: " << Add (3,4);
std::cout << "\nback to main ().\n";
std::cout << "\nout..\n\n";
return 0;
}
如果我使用 MSVC 编译器编译它,结果是:
In main ()
Calling Add ()
In Add(), received 3 and 4
value: 7
back to main ().
out..
但在 GCC 中,结果是:
In main ()
Calling Add ()
value: In Add(), received 3 and 4
7
back to main ().
out..
为什么输出不一样?我还想知道是否有办法让两个编译器具有相同的输出。
答:
3赞
Quimby
10/8/2023
#1
在 c++17 之前,运算符不是排序点,因此可以按任何顺序计算。<<
std::cout << "value: " << Add (3,4);
C++17 保证从左到右进行评估,这在您的情况下是错误的行为。
我的猜测是您使用的编译器的特定版本具有不同的默认 C++ 版本,并且 MSVC 从右到左计算表达式。
应将表达式拆分为多个语句。一般来说,我的建议是将计算与报告分开,即在日志记录或其他条件(如)部分中没有任何计算。assert
评论
0赞
Jan Schultke
10/8/2023
评估顺序保证仅与内置运算符相关。在这种情况下,使用运算符重载。C++ 17 中函数调用的评估顺序保证也发生了变化,所以这个问题本质上是正确的,但它是不准确的。<<
<<
1赞
user17732522
10/8/2023
@JanSchultke C++17 还更改了由运算符的过载解析导致的函数调用操作数的评估保证顺序,以匹配内置运算符的计算顺序:eel.is/c++draft/over#match.oper-2.sentence-4
评论
auto value{ Add(3, 4) }; std::cout << "value: " << value;
将使两个编译器(在它们使用的任何 C++ 标准设置下)具有相同的输出。