GCC 忽略默认成员值初始化

default member value initialization is ignored in GCC

我在下面的代码中发现了一个意想不到的行为(据我所知),它不遵守默认成员初始化值。我有一个承包商用于单个参数赋值,它应该从赋值运算符构建 class 。我忘了使用正确的参数名称,结果遇到了这个问题(请参阅带有故意错误的单参数构造函数行:

为什么我得到的是垃圾值而不是成员初始化值?

我自己的假设是因为模板化 class,00.0 不同...但尝试过它与 并遇到了同样的问题。

#include <iostream>
#include <concepts>


template <class T>
requires std::is_arithmetic_v<T>
class Complex
{
private:
    T re = 0;
    T im = 0;

public:

    Complex() {
        std::cout << "Complex: Default constructor" << std::endl;
    };

    Complex(T real) : re{re} { // should be re{real}, but why re{re} is not 0?
        std::cout << "Complex: Constructing from assignement!" << std::endl;
    };

    void setReal(T t) {
        re = t;
    }

    void setImag(const T& t) {
        im = t;
    }

    T real() const {
        return re;
    }

    T imag() const {
        return im;
    }

    Complex<T>& operator+=(const Complex<T> other) {
        re+= other.re;
        im+= other.im;
        return *this;
    }

    bool operator<(const Complex<T>& other) {
        return (re < other.re && im < other.im);
    }

};

int main() {
    
        Complex<double> cA;
         std::cout<< "cA=" << cA.real() << ", " << cA.imag() << "\n";

        Complex<double> cB = 1.0; // Should print "1.0, 0" but prints garbage
         std::cout<< "cB=" << cB.real() << ", " << cB.imag() << "\n";

    Complex<int> cC = 1;
    std::cout<< "cC=" << cC.real() << ", " << cC.imag() << "\n";
        
        return 0;
}

示例输出:

Complex: Default constructor cA=0, 0 Complex: Constructing from assignement! cB=6.91942e-310, 0 Complex: Constructing from assignement! cC=4199661, 0

代码在CompilerExplorer.

Complex(T real) : re{re} { // should be re{real}, but why re{re} is not 0?

如果您在构造函数中显式地为成员提供初始值设定项,则此初始值设定项替换默认成员初始值设定项。默认成员初始值设定项在这种情况下根本不使用。

需要说明的是:默认成员初始值设定项不会在调用构造函数之前初始化成员。它们只是“填充”构造函数的成员初始化器列表中未提及的成员的初始化器。

在你的例子中,re{re} 访问了一个超出其生命周期的对象 (re),导致了未定义的行为。


此外,作为旁注:Complex<double> cB = 1.0;Complex<int> cC = 1; 不是 作业 。两者都是带有初始化的声明。 = 不是赋值表达式的一部分,不会像赋值那样调用 operator= 。它们都是 copy-initialization,与 Complex<double> cB(1.0); 相反,后者是 direct-initialization.

这些初始化所使用的构造函数 Complex(T real) 称为 转换构造函数