初始化 POD 数组中的第一个元素,其余元素未初始化

Posted

技术标签:

【中文标题】初始化 POD 数组中的第一个元素,其余元素未初始化【英文标题】:Initialize first element in POD array, leave remaining elements uninitialized 【发布时间】:2016-05-07 11:24:08 【问题描述】:

我正在使用关键路径上的函数。代码如下所示:

void ProcessData(const byte* input, size_t size)

    ALIGN_ARRAY(16) int32_t m0[2] =  ((const int32_t*)input)[0] ;
    ALIGN_ARRAY(16) int32_t m1[2] =  ((const int32_t*)input)[1] ;
    ...

第一个元素m0[0] 是我关心的元素。第二个元素m0[1] 是暂存空间,在m 被运送到SIMD 引擎之前保持对齐。 m0[1] 将填充一个值,但我不需要初始化它。

这段代码被反复调用,对基准测试结果影响很大,因此将所有内容最小化很重要。我希望编译器知道它可以初始化第一个元素,因为代码可能会得到更好的优化。

如何确保仅初始化第一个元素,而未初始化数组中的其余元素?有没有可能?


这个问题与Initialization of a normal array with one default value、Static array initialization of individual elements in C++和Array initialization with 0, 0,?之类的问题相反

我也知道初始化不同于赋值;以及zero-, default- and value-initialization 的一些细节以及 POD 对其有何影响。

【问题讨论】:

你要么什么都不初始化,要么初始化一切。在您的情况下,保持数组未初始化,然后分配给它的第一个元素。 感谢@KerrekSB。我有点害怕那个。既然如此,那你也不妨作个记录。 【参考方案1】:

不确定输入的内容,尤其是因为它具有字节类型并且您正在转换为 int32。如果您使用的是 x86 平台,请注意后置词(字节序问题)。

尝试类似的方法,但使用适当的演员表。

void ProcessData(const byte* input, size_t size)

    ALIGN_ARRAY(16) int32_t m0[2];
    m0[0]= = (const int32_t*)input)[0];
    ALIGN_ARRAY(16) int32_t m1[2];
    m1[0] = (const int32_t*)input)[1];
    ...

【讨论】:

【参考方案2】:

使用堆栈分配的数组是不可能的。即使在 C++03 中,初始化器列表中的任何省略元素都是默认初始化(如果是类类型)或值初始化(如果不是)。您有两种选择:

    保持数组未初始化,初始化一个元素。 使用类包装器。 过度设计场景。

你可以这样做。

const uint8_t input[...];

std::pair< int32_t*, std::ptrdiff_t > ms[...];

for (int i = 0; i < ...; ++i)

    ms[i] = std::get_temporary_buffer<int32_t>(2);
    std::copy((const int32_t*)input + i, (const int32_t*)input + i + 1,
              std::raw_storage_iterator<int32_t*, int32_t>(ms[i].first));

// later loop std::return_temporary_buffer(ms[...].first); at end of function

【讨论】:

以上是关于初始化 POD 数组中的第一个元素,其余元素未初始化的主要内容,如果未能解决你的问题,请参考以下文章

我可以防止非 POD 类中数组数据成员中元素的零初始化吗?

测试未初始化的数组元素不起作用

C语言一维数组赋值方法

c语言定义一维数组,元素未初始化,那数组元素默认值是啥

从初始数组中删除与初始数组后跟的参数值相同的所有元素

如何用js push() 初始化一个二维数组