【问题标题】:Array of objects not initialized to 0未初始化为 0 的对象数组
【发布时间】:2019-11-05 15:26:39
【问题描述】:

我正在尝试像这样用 0 初始化一个对象数组(更复杂项目的简化代码):

#include <iostream>

struct Vector {
    float s[4];
    Vector() {}
    static Vector zero() {
        Vector v;
        v.s[0] = 0;
        v.s[1] = 0;
        v.s[2] = 0;
        v.s[3] = 0;
        return v;
    }
};

struct Test {
    Vector v[4] = { Vector::zero() };
};


int main(int argc, char** argv)
{
    Test t;
    for (int i = 0; i < 4; i++) {
        printf("%f %f %f %f\n", t.v[i].s[0], t.v[i].s[1], t.v[i].s[2], t.v[i].s[3]);
    }
    return 0;
}

此代码应打印全 0,但有时会打印不同的值。看起来只有数组的第一个元素被初始化。但是如果我写 float x[4] = { 0 },那么数组 x 的所有元素都用 0 初始化。有什么区别,我可以在 C++ 标准的什么地方了解这种行为?

【问题讨论】:

  • 使 s 全局化,它的元素将被初始化为 0
  • @Cornstalks 谢谢,我修好了,但没有改变根本问题。
  • @QuentinUK 谢谢,我知道,但我不能这样做 :-)
  • 我有点困惑。如果您对未提及标准的答案感到满意,您为什么要求参考标准?
  • 如果是 std::array 教练应该强迫你使用而不是阻止,恕我直言,我会更高兴。

标签: c++ language-lawyer


【解决方案1】:

我想你可能想看看这里:https://en.cppreference.com/w/cpp/language/aggregate_initialization

Vector v[4] = { Vector::zero() };

您初始化第一个元素,其他 3 个通过调用未初始化数组的默认 ctor 进行初始化(默认 ctor 的主体为空)。

替换数组声明的开头
float s[4]{};

这将对数组进行值初始化,将其归零。然后你可以删除其他所有内容。

读值初始化和零初始化的关系请参考https://en.cppreference.com/w/cpp/language/value_initialization

此外,正如用户 Kenny Ostrom 在 cmets 中所指出的,您可能需要考虑使用 std::array,请记住您仍需要对其进行值初始化,请参阅 Default initialization of std::array?。 最后,如 cmets 中所述,对 x[4] 的访问是未定义行为。

【讨论】:

  • 谢谢,我修复了原始帖子中的 x[4] 访问权限。我不知道我是否可以将它更改为 std::array,它在一个联合中并且有一些对齐要求。发生问题的原始代码在这里:github.com/VCVRack/Fundamental/blob/… 这是没有初始化的有问题的行,我现在建议将其更改为您的解决方案:github.com/VCVRack/Rack/blob/…(同一文件具有 float_4 的 typedef)
  • 恕我直言,替换应该没问题,但我不确定,我不是工会的粉丝,请参阅stackoverflow.com/questions/21763002/…。您可能需要考虑使用变体(std 或 boost)而不是普通的 union。
  • @FrankBuss,这里不是工会专家,但恐怕我的解决方案可能不适合您的特定用例,请参阅stackoverflow.com/questions/11812555/…
  • 开发者现在已经在构造函数中归零了:github.com/VCVRack/Rack/commit/… 应该是安全的。唯一的问题是它假定 sizeof(float)==4,但可能适用于所有支持的平台。
  • 太棒了!您可以考虑将 static_asset(sizeof(float) == 4, "ERROR") 添加到代码中,这样如果大小不是 4,它将无法编译,并且您知道它是编译时而不是运行时。问候
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 2017-02-16
  • 2018-09-19
相关资源
最近更新 更多