由于C和C++中的序列点,您遇到了哪些问题?

yes*_*aaj 4 c c++ sequence-points

以下是由于序列点规则导致未定义行为的两个常见问题:

a[i] = i++; //has a read and write between sequence points
i = i++;   //2 writes between sequence points
Run Code Online (Sandbox Code Playgroud)

您在序列点方面遇到的其他事情是什么?

当编译器无法警告我们时,很难找到这些问题.

jal*_*alf 10

达里奥的一个例子是:

void Foo(shared_ptr<Bar> a, shared_ptr<Bar> b){ ... }

int main() {
  Foo(shared_ptr<Bar>(new Bar), shared_ptr<Bar>(new Bar));
}
Run Code Online (Sandbox Code Playgroud)

这可能会泄漏内存.在评估两个参数之间没有序列点,因此不仅可以在第一个参数之前评估第二个参数,而且还可以在任何一个参数之前创建两个Bar对象shared_ptr.

也就是说,而不是被评估为

Bar* b0 = new Bar();
arg0 = shared_ptr<Bar>(b0);
Bar* b1 = new Bar();
arg1 = shared_ptr<Bar>(b1);
Foo(arg0, arg1);
Run Code Online (Sandbox Code Playgroud)

(这将是安全的,因为如果b0成功分配,它会立即包装在a中shared_ptr),它可以被评估为:

Bar* b0 = new Bar();
Bar* b1 = new Bar();
arg0 = shared_ptr<Bar>(b0);
arg1 = shared_ptr<Bar>(b1);
Foo(arg0, arg1);
Run Code Online (Sandbox Code Playgroud)

这意味着如果b0成功分配,并b1抛出异常,那么b0永远不会被删除.


Dar*_*rio 6

关于参数列表中的执行顺序或例如添加,存在一些不明确的案例.

#include <iostream>

using namespace std;

int a() {
    cout << "Eval a" << endl;
    return 1;
}

int b() { 
    cout << "Eval b" << endl;
    return 2;
}

int plus(int x, int y) {
    return x + y;
}

int main() {

    int x = a() + b();
    int res = plus(a(), b());

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

先执行()或b()吗?;-)