现代c ++

时间:2018-02-08 03:04:18

标签: c++ visual-studio

当我运行此代码时,VS编译器返回错误,并说t1.mem是未初始化的局部变量。

#include <string>
#include <iostream>
struct T1
{
  int mem;
};

struct T2
{
  int mem;
  T2() { } // "mem" is not in the initializer list
};


int main()
{

  T1 t1;            // class, calls implicit default ctor
  std::cout << t1.mem << std::endl;
  const T2 t2;      // const class, calls the user-provided default ctor
                  // t2.mem is default-initialized (to indeterminate value)
  std::cout << t2.mem << std::endl;

}

如果我没有为struct T1分配构造函数,编译器必须生成默认构造函数?而struct T2的构造函数是空的初始化列表,为什么它没有错误提示?

2 个答案:

答案 0 :(得分:0)

我的理解是编译器试图保护您免受其自己生成的代码的影响,并在使用您提供的构造函数时假定“您最了解”。另外,检查你的构造函数是否实际上最终在任何地方初始化T2.mem,包括在构造函数的主体中,可能是一个任意复杂的任务,因此编译器作者可能已经确定这是一个比未尝试更好的任务。执行不力。

如果您将t1声明为const T1,则似乎得到MSVC的warning you would get支持:

  使用编译器生成的默认构造函数初始化的

'const'自动数据会产生不可靠的结果

注意“编译器生成的默认构造函数”一词。

顺便说一句,如果您使用T2() = default请求编译器生成的默认构造函数,您将看到同样的警告。

答案 1 :(得分:0)

好吧,编译器并不完美。有时他们警告一件事,但他们不会做另一件事,类似的事情。许多编译器还提供生成代码的运行时检测,其中它们插入特殊指令来检测错误,例如使用未初始化的变量,并在发生时中止程序。但同样,系统并不完美,它可能会错过任何东西。

无论如何,您实际上并不需要构造函数。您可以内联初始化类成员:

struct T1
{
    int mem = 0;
};

默认情况下将使用内联初始化,除非构造函数将成员初始化为其他内容:

struct T1
{
    int mem = 0;

    T1() = default;

    T1(int m) : mem(m) { }
};
// ...
T1 first; // first.mem == 0
T1 second(1); // second.mem == 1