含未初始化成员struct的vector是否触发undefined behavior?并行填充问询
当std::vector包含带有未初始化成员的struct时,是否会触发未定义行为?
结论先行:只要严格保证未初始化的成员在完成赋值前绝不会被读取,这种实现就不会触发未定义行为(UB)。
具体分析:
未初始化值的UB触发条件
C++标准中,只有当你读取未初始化的标量类型值时才会导致UB。对于uninitialized<T>的默认构造函数,它没有初始化成员t——以int为例,此时t的值是不确定的,但只要你在任何读取操作(比如用t做计算、传递给函数)之前,通过operator=完成赋值,就完全合规。std::vector构造的行为
std::vector<uninitialized<int>>(500)会调用500次uninitialized<int>的默认构造函数,此时每个元素的t成员处于未初始化状态,但这本身并不违反标准——标准允许存在未初始化的对象,只有非法读取才会触发UB。后续的循环(或并行填充逻辑)通过赋值覆盖了t的值,完全规避了读取风险。适配你的使用场景
- 针对你提到的简单数值类型或聚合类型:这类类型的未初始化成员同样遵循“不读取就无UB”的规则,后续赋值可以安全覆盖。
- 关于
reserve + push_back不适用的问题:当前直接构造固定大小vector的方式,既保证了元素顺序,又跳过了普通T类型默认初始化的开销,正好匹配你“避免default initialization浪费”的需求,适合并行填充的场景。
注意事项
务必确保所有代码路径中,都不会在赋值前读取uninitialized<T>::t——包括调试代码、隐式的类型转换或函数调用(比如不小心把t传入某个打印函数)。只要守住这个边界,你的实现就是安全的。
示例代码:
template< typename T > struct uninitialized { T t; uninitialized(){}; uninitialized & operator=( T const & inT ){ t = inT ; return *this; } uninitialized & operator=( T && inT ){ t = std::move( inT ); return *this; } }; std::vector< uninitialized< int > > example() { auto vector = std::vector< uninitialized< int > >(500); // Other code unrelated to vector for( auto & element : vector ) element = 0; // For loop as stand in for potentially parallel context // "0" is simply used as a stand in to keep the example simple // Code which might use vector return vector; }
内容的提问来源于stack exchange,提问作者Sam Coutteau
相关产品推荐
相关产品推荐

