【问题标题】:g++ vs intel/clang argument passing order?g++ vs intel/clang 参数传递顺序?
【发布时间】: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 标准,哪一个是正确的?

【问题讨论】:

  • 找到评估顺序的好方法。

标签: c++ c++11 arguments standards-compliance chrono


【解决方案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>.
    猜你喜欢
    • 2013-03-12
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-08
    • 2013-08-21
    相关资源
    最近更新 更多