GCC错误?链接方法,断点序列点 [英] GCC bug? Chaining methods, broken sequence point

查看:216
本文介绍了GCC错误?链接方法,断点序列点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在调试一个程序一段时间,最终发现错误是由于一个引用不更新,因为我认为这是。

I've been debugging a program for some time, and eventually found the error was due to a reference not being updated as I thought it would be.

这里显示我遇到的问题的示例:

Here's a example that shows the problem I encountered:

#include <iostream>
using namespace std;

struct Test {
    Test& set(int& i){ i = 10; return *this; }
    Test& print(const int& i){ cout << i << endl; return *this; }
};

int main(void){
    int i = 0;
    Test t;

    t.set(i).print(i + 5);

    return 0;
}



我希望print()方法输出15,它输出5。

I had expected that the print() method here would output 15, but instead it outputs 5.

编辑:10天后我才意识到,用clang它输出15!这是GCC中的错误吗?

10 days later I just realised that with clang it outputs 15! Is this a bug in GCC?

推荐答案

让我尝试解释C ++ 11标准。在§1.9/ 15中,它表示:

Let me try interpreting the C++11 standard on this. In §1.9/15 it says:


除非另有说明,否则单个运算符的操作数和单个表达式的子表达式的求值不受影响。 [...]如果对标量对象的副作用相对于对同一标量对象的另一个副作用或使用同一个标量对象的值的计算没有序列,行为是未定义的。

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [...] If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.

当然 int 是标量类型, t.set(i) .print(i + 5); 包含对 i 在 set()中的副作用和值计算 i + 5 ,所以如果没有另外说明,行为的确是未定义的。阅读§5.2.5(类成员访问),我找不到关于运算符的序列的任何注释。 [但请参阅下面的编辑!]

Certainly int is an scalar type, and t.set(i).print(i + 5); contains a side effect on i in set() and the value computation i + 5, so if not noted otherwise, the behavior is indeed undefined. Reading §5.2.5 ("Class member access"), I could not find any notes about sequences regarding the . operator. [But see edit below!]

但是,当然可以保证 set() print(),因为后者接收前者的返回值作为(隐式 this )参数。
这里的罪魁祸首是 print 的值计算是无序的相对于 set

Note, however that it is of course guaranteed that set() is executed before print() because the latter receives the return value of the former as an (implicit this) argument. The culprit here is that the value computation for print's arguments is unsequenced indeterminately sequenced relative to the call of set.

编辑:阅读了你的(@ Xeno的)评论中的答案后,我重读了标准中的段落,事实,它后来说:

After reading the answer in your (@Xeno's) comment, I reread the paragraph in the standard, and in fact it later says:


在执行之前或之后,调用函数中的每个评估(包括其他函数调用)

Every evaluation in the calling function (including other function calls) that is not otherwise specifically sequenced before or after the execution of the body of the called function is indeterminately sequenced with respect to the execution of the called function.

因为不确定顺序

Because indeterminately sequenced is not unsequenced ("execution of unsequenced evaluations can overlap", §1.9/13), this is indeed not undefined behavior, but "just" unspecified behavior, meaning that both 15 and 5 are correct outputs.

所以当< code>表示不确定顺序,我们有:

So when < means "sequenced before" and ~ means "indeterminately sequenced", we have:

))执行的print()

这篇关于GCC错误?链接方法,断点序列点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆