由于std :: complex是非平凡的类型,请使用GCC 8.1.1编译以下内容
complex<double>* z = new complex<double>[6];
memset(z,0,6*sizeof*z);
delete [] (z);`
发出警告
清除非平凡类型的对象
我的问题是,这样做实际上有潜在的危害吗?
答案 0 :(得分:4)
仅在std::memset
的行为是指向TriviallyCopyable类型的指针时才定义其行为。 std::complex
被保证为 LiteralType ,但据我所知,它不能保证为 TriviallyCopyable ,这意味着{{1} }不可移植。
也就是说,std::memset(z, 0, ...)
有一个array-compatibility guarantee,它表示std::complex
的存储正好是两个连续的std::complex<T>
,可以照此重新解释。这似乎表明T
实际上很好,因为它将通过这种面向数组的访问进行访问。这也可能暗示std::memset
是 可完全复制的,但我无法确定。
如果您希望这样做,建议您保持安全,并std::complex<double>
声明static_assert
是 TriviallyCopyable :
std::complex<double>
如果该断言成立,那么可以保证static_assert(std::is_trivially_copyable<std::complex<double>>::value);
是安全的。
在两种情况下,都可以使用memset
:
std::fill
它optimizes down是对std::fill(z, z + 6, std::complex<double>{});
的调用,尽管之前还有一些其他说明。我建议使用memset
,除非您的基准测试和性能分析表明这几条额外的说明会引起问题。
答案 1 :(得分:1)
永远,永远,永远memset
个非POD类型。他们有一个构造器。仅在它们上面写入一堆字节是不太可能给出期望结果的(如果确实如此,则类型本身设计不良,因为它们应该清楚地放在首位,否则它们应该是POD -否则,您很不幸在这种情况下,未定义行为似乎可以工作-在更改优化级别,编译器或平台(或月相)后,如果没有进行调试,请尝试调试它。 >
请不要这样做。
答案 2 :(得分:0)
这个问题的答案是,对于符合标准的wordToken "the man saw."
> ["the", "man", "saw", "."]
,在std::complex
之后不需要memset
。
new
将复数初始化为new complex<double>[6]
,因为它调用了初始化为零的默认(非平凡)构造函数。
(不幸的是,我认为这是一个错误。)
https://en.cppreference.com/w/cpp/numeric/complex/complex
如果发布的代码是公正的,并且示例在(0, 0)
和new
之间缺少代码,那么memset
将做正确的事情。
(部分原因是特定的标准库实现内部了解std::fill
的实现方式。)