因为 std::complex 是一个非平凡的类型,使用 GCC 8.1.1 编译以下内容
complex<double>* z = new complex<double>[6];
memset(z,0,6*sizeof*z);
delete [] (z);`
产生警告
clearing an object of non-trivial type
我的问题是,这样做真的有任何潜在的危害吗?
最佳答案
std::memset
的行为仅当它正在修改的指针是指向 TriviallyCopyable 的指针时才定义类型。 std::complex
保证是 LiteralType,但据我所知,它不能保证是 TriviallyCopyable,这意味着 std::memset(z, 0, ...)
不便携。
也就是说,std::complex
有一个 array-compatibility guarantee ,它指出 std::complex<T>
的存储正好是两个连续的T
s 并且可以这样重新解释。这似乎表明 std::memset
实际上很好,因为它将通过这种面向数组的访问进行访问。这也可能意味着 std::complex<double>
是 TriviallyCopyable,但我无法确定。
如果您想这样做,我建议您安全起见并且static_assert
那个 std::complex<double>
是TriviallyCopyable:
static_assert(std::is_trivially_copyable<std::complex<double>>::value);
如果该断言成立,那么可以保证 memset
是安全的。
无论哪种情况,使用 std::fill
都是安全的:
std::fill(z, z + 6, std::complex<double>{});
它optimizes down调用电话 memset
,尽管之前还有一些说明。我建议使用 std::fill
除非您的基准测试和分析表明那几条额外的指令导致了问题。
关于c++ - memset 和 std::complex<double> 的动态数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51658046/