运算符new的执行顺序和构造函数的参数


9

C ++规范是否指定in 的顺序operator new和构造函数。 g ++的顺序为-> -> ,而clang ++ 的顺序为-> -> 。 差异是由未指定的行为引起的吗?Anew C(A())
A()newC()newA()C()

g ++:7.4.0 clang ++:10.0.0

#include <iostream>
#include <cstdlib>

struct A {
    A() {
        std::cout << "call A()\n";
    }
};

struct C {
    C(A) {
        std::cout << "call S()\n";
    }

    void *operator new(size_t s) {
        std::cout << "call new()\n";
        return malloc(s);
    }
};

int main() {
    void *p = new C(A());
}

3
您要构建为C ++ 17,C ++ 14或更低版本吗?
StoryTeller-Unslander Monica,

4
两个注意事项:您用“ C”标记了该标记,这清楚地表明您没有阅读该标记的描述。别。现在,您询问“未定义的行为”(UB)。这是C ++标准使用的术语,用于标记可能发生任何事情并且应避免的事情。还有一种“未指明的行为”,它可能更接近您所追求的,因为该代码在技术上是可以正常使用的,并且不会导致UB。
Ulrich Eckhardt

1
@Ulrich Eckhardt谢谢您的建议。我把两者混在一起。
eddie kuo

Answers:


11

lang是正确的。从C ++ 17开始,可以保证执行顺序。[expr.new] / 19

分配函数的调用在new-initializer中对表达式求值之前进行排序。

operator new(分配函数)应该先被调用,然后在new-initializer中对表达式求值(即A())。

在C ++ 17之前,不能保证顺序。[expr.new] / 18(C ++ 14)

对于new初始化程序中的表达式求值,分配函数的调用不确定地排序。


看来gcc不符合C ++ 17(及更高版本);在C ++ 2a模式下使用gcc10进行编译可获得相同的结果。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.