如果我这样做:
static int counter = 0;
counter = std::min(8, counter++);
我收到g ++的警告:
operation on 'counter' may be undefined [-Wsequence-point]
这很好用:
static int counter = 0;
counter++;
counter = std::min(8, counter);
结果与++counter
和/或std::max
相同。
我无法弄清楚第一个版本有什么问题。这也发生在std :: max上。举个例子,我在使用GLM中的函数时没有得到任何警告。
任何人都可以为我解释一下吗?我在Ubuntu 14.04上使用GCC 4.8。
编辑:多一点测试(我应该先做)
如果我执行cntr = std::min(8, ++cntr);
,就像我在实际应用程序中一样,在此行之后打印值会导致1,然后是2,然后是3,等等。但是,如果我执行cntr = std::min(8, cntr++);
,则vaule为0无论如何,它永远不会增加。
答案 0 :(得分:0)
我认为Mike Seymour的评论是正确的 - 应该没有UB,因为函数参数表达式应该在函数调用之前排序。从1.19 / 15:
当调用函数时(无论函数是否为内联函数),在执行每个表达式或语句之前,对与任何参数表达式或指定被调用函数的后缀表达式相关联的每个值计算和副作用进行排序。被调用函数的主体。
所以gcc可能不正确。另请注意,在某些其他情况下,警告不会显示:
int f(int a, int b);
template <typename T> T g(T a, T b);
template <typename T> const T& h(const T& a, const T& b);
counter = f(8, counter++); // no warning
counter = g(8, counter++); // no warning
counter = h(8, counter++); // gcc gives warning - there should be nothing special
// about h as compared to f,g... so warning is likely
// incorrect
clang没有发出任何警告。
鉴于函数参数在调用之前已经排序,这就解释了为什么:
int counter = 0;
counter = std::min(8, counter++);
始终返回0.该代码相当于:
counter = 0;
int a1 = 8; // these two can be evaluated in either order
int a2 = counter++; // either way, a2 == 0, counter == 1
counter = std::min(a1, a2); // which is min(8, 0) == 0.