g++ vs intel/clang 参数传递顺序?

Posted

技术标签:

【中文标题】g++ vs intel/clang 参数传递顺序?【英文标题】:g++ vs intel/clang argument passing order? 【发布时间】:2013-03-04 15:57:36 【问题描述】:

考虑以下代码 (LWS):

#include <iostream>
#include <chrono>

inline void test(
   const std::chrono::high_resolution_clock::time_point& first, 
   const std::chrono::high_resolution_clock::time_point& second)

   std::cout << first.time_since_epoch().count() << std::endl;
   std::cout << second.time_since_epoch().count() << std::endl;


int main(int argc, char* argv[])

   test(std::chrono::high_resolution_clock::now(), 
        std::chrono::high_resolution_clock::now());
   return 0;

您必须多次运行它,因为有时没有明显的差异。但是当firstsecond的求值时间有明显差异时,g++下的结果如下:

1363376239363175
1363376239363174

以及 intel 和 clang 下的以下内容:

1363376267971435
1363376267971436

表示g++下second参数先求值,intel和clang下first参数先求值。

根据 C++11 标准,哪一个是正确的?

【问题讨论】:

找到评估顺序的好方法。 【参考方案1】:

我有一个稍微简单的例子来说明同样的问题。

bash$ cat test.cpp
#include <iostream>
using namespace std;
int x = 0;
int foo() 

    cout << "foo" << endl;
    return x++;

int bar()

    cout << "bar" << endl;
    return x++;

void test_it(int a, int b)

    cout << "a = " << a << endl
        << "b = " << b << endl;


int main(int argc, const char *argv[])

    test_it(foo(),bar()); 
    return 0;


bash$ clang++ test.cpp && ./a.out
foo
bar
a = 0
b = 1
bash$ g++ test.cpp && ./a.out
bar
foo
a = 1
b = 0

【讨论】:

【参考方案2】:

根据 C++11 标准,哪一个是正确的?

两者都是允许的。引用标准(§8.3.6):

函数参数的求值顺序未指定。

【讨论】:

是的。事实上,在我的职业生涯中,这曾多次困扰我。函数参数评估的模棱两可会导致极其微妙的问题。 (我记得有一次这个错误存在多年,但我找不到根本原因,我能找到的唯一解决方法是关闭对该 CPP 的优化。哎呀。) 此外,顺序可能取决于使用的优化标志和其余代码。 @StilesCrisis 是的,即使您知道未定义的参数评估顺序,您也必须记住,调用方法的对象也只是另一个参数。有一次发生在我身上,因为我想“嗯,要通过-&gt; 调用一个方法,它必须首先评估左侧,然后才能开始查看方法参数,不是吗?” i>.

以上是关于g++ vs intel/clang 参数传递顺序?的主要内容,如果未能解决你的问题,请参考以下文章

C# vs Python 参数传递

2015.3.5 VS2005调用VC6 dll 时结构参数的传递

vs 中项目与 dll 一起调试和参数传递

WPF如何获取命令行参数

g:消息多个参数传递

关于C#ref关键词一个问题,VS提示参数1不应使用关键字ref传递,我想知道修改使a,b的值都进行引用传递