获得一个默认初始化(NOT值/初始化为零)POD作为右值

问题描述:

#include <iostream> 

struct A { 
    int x; 
}; 

void foo(A a) { 
    std::cout << a.x << std::endl; 
} 

int main() { 
    A a; 
    foo(a); // -7159156; a was default-initialized 
    foo(A()); // 0; a was value-initialized 
} 

是否有可能A类型的右值传递给foo()没有价值的初始化呢?我们必须使用值初始化还是左值?获得一个默认初始化(NOT值/初始化为零)POD作为右值

您可能会问,当“成本”不超过10纳秒时,避免初始值初始化的意义何在?这样的情况如何:我们正在寻找遗留应用程序中由valgrind的未初始化内存访问引起的错误,并且零不被视为应用程序的有效值。值初始化将防止valgrind发现未初始化的内存访问的位置。

您可能会说打印未初始化的值是UB,但我的“真实”用例不限于打印。没有它,我的问题应该仍然有效。

+0

未初始化的类成员是否定义了行为? –

+1

'A'是否必须勾选所有的POD盒?如果你可以给它一个空的用户提供的默认构造函数,那么值初始化就等同于默认初始化,并且你得到你想要的未定义行为;-)。 – bogdan

+0

@bogdan'A'可能超出我的控制范围。例如。 'struct tm' – nodakai

如果我理解正确的问题,您需要更换foo(A());或类似的情况,其中A()被调用,以便您没有默认的成员初始化。

在这里这种情况下,一个就是我想出了:

  • 首先,我试图添加A() = default(但是这可能不会与旧的C++标准的制定工作),我不得不interesting results。您提供的确切样本首先在反向打印0中工作,然后是一些随机数。

  • 其次我没有使用A() = default;,只是使用的模板函数

    template <class T> T make() { T tmp; return tmp; } 
    

    在副本的成本(或移动),你可以使用它像foo(make<A>())并得到你想要的结果。