【发布时间】:2020-03-22 01:34:34
【问题描述】:
我很难理解以下从cppreference 引用的关于琐碎默认构造函数的段落。我已经搜索了stackoverflow,但仍然没有得到明确的答案。所以请帮忙。
平凡的默认构造函数是不执行任何操作的构造函数。所有与 C 语言兼容的数据类型(POD 类型)都可以简单地默认构造。然而,与 C 不同的是,不能通过简单地重新解释适当对齐的存储来创建具有普通默认构造函数的对象,例如使用 std::malloc 分配的内存:placement-new 需要正式引入新对象并避免潜在的未定义行为。
具体来说,如果微不足道的默认构造函数什么都不做,为什么我们不能重新解释存储并假装存在具有给定类型的对象?您能否提供一些示例来说明这会导致的潜在的未定义行为?
【问题讨论】:
-
编译器最重要的工作不是编译源代码,而是拒绝可能无效的代码。当你使用 malloc() 时它不能这样做。
-
原因很简单。程序员做疯狂事情的机会越少,编译器做疯狂事情的机会就越多(积极优化)。
-
出于类似的原因,您不能只使用
*reinterpret_cast<float*>(&someNonFloatObject) = 0.1f;。 C++ 有对象和对象生命周期的概念,在抽象机上指定,仅仅因为没有 CPU 指令从存储创建对象并不意味着在抽象机上没有区别。 -
@HansPassant 拒绝所有代码的编译器会拒绝所有无效代码。无论如何,拒绝有 UB 的程序不是编译器的工作。
标签: c++ language-lawyer