【问题标题】:C++ partial constructors with and without a body behave differently带有和不带有主体的 C++ 部分构造函数的行为不同
【发布时间】:2019-11-20 19:15:55
【问题描述】:

考虑以下 C++ 代码:

#include <iostream>
#include <string>

#define DUMP(_, str) do {                      \
    std::cout << str;                          \
    for (int i = 0; i < 10; ++i)               \
        std::cout << (_).x[i] << std::endl;    \
    std::cout << "a = " << (_).a << std::endl; \
    std::cout << "b = " << (_).b << std::endl; \
    std::cout << "c = " << (_).c << std::endl; \
    std::cout << "d = " << (_).d << std::endl; \
    std::cout << std::endl;                    \
} while (0)

//#define ENABLE_WTF

struct A {
    int x[10];
    float a, b, c, d;

#ifndef ENABLE_WTF
    A() : d(4) { DUMP(*this, "=== INSIDE CTOR ===\n"); }
#else
    A() : d(4) {}
#endif
};

int main() {
    A a;
    DUMP(a, "=== OUT OF CTOR ===\n");
}

可以看出,A 有一个部分构造函数,它只初始化一个字段,而所有其他字段可以预见地仍然是垃圾; demonstration here.

现在的问题是:当它的部分构造函数没有主体 (demonstration here) 时,它是编译器特定的,以将 A 的其余部分归零,还是它是 C++ 本身的一部分?

【问题讨论】:

  • 无法重现:godbolt.org/z/ysUqYG
  • 我用不同的编译器和命令行选项多次注释/取消注释它,但从未看到全零。
  • @Evg Hm,所以看起来我目前使用的编译器(ICPC 19.0)恰好与运行 cpp.sh 的编译器类似。过失,我没有考虑过这种可能性,因此错误地认为这种行为是普遍的。

标签: c++ constructor language-lawyer raii


【解决方案1】:

使用给定的构造函数

A() : d(4) { ... }

d 之外的所有数据成员都将被默认初始化。对于内置类型,这是无操作的,并且这些数据成员将具有不确定的值。读取它们的值是未定义的行为。

一些编译器might initialize 调试版本中的此类数据成员使用特定的字节模式来帮助捕获运行时错误。

【讨论】:

    猜你喜欢
    • 2021-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 2019-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多