为什么删除不完整的类型定义为"undefined behaviour"?
Why is the deletion of an incomplete type defined as "undefined behaviour"?
为什么删除不完整类型定义为"未定义行为"?
来自C++规范;§5.3.5/5;
如果要删除的对象在删除时具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为未定义。
给定代码示例(我理解为什么它是一个错误);
class ABC;
int main()
{
ABC* p = nullptr;
delete p;
}
当gcc、clang和msvc都警告它是一个不完整的类型时,为什么它被定义为是未定义的行为?为什么不只是在这一点上出错,即为什么它不是可诊断的错误?
因为,正如您的引号所说,只有当它具有非平凡的析构函数或释放函数时,它才是未定义的行为。如果它是不完整的,编译器不知道情况是否如此,也不知道程序是否定义良好。
表达式delete p;
做两件事:
- 销毁包含
*p
的完整对象 - 取消分配用于存储所述对象的内存
当您只知道对象的地址,而不需要任何进一步的信息时,项目2可能是。内存分配器只关心地址。但是,确定完整对象的地址可能很困难;您基本上需要保证您实际上提供了一个完整对象的地址。
但还有更多。在释放对象的存储之前,必须运行析构函数(项1)。如果析构函数没有效果,那么不运行析构函数是可以接受的,因为这与运行它们时的行为相同。但是,如果运行析构函数确实有效果,那么省略第1项会导致未定义的行为,并且您需要知道完整的类型才能知道如何运行destrutors。同样,您还需要知道完整的类型,以便确定项2的派生对象最多的地址。
相关文章:
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- Visual Studio Code "undefined reference to `WinMain@16'"
- 使用 MATLAB 编码器生成C++代码:编译错误"undefined reference to `rgb2gray_tbb_real64'"
- "Undefined class"作为is_base_of的论据
- 为什么创建友元类的实例会导致"undefined reference to"错误?
- Tensorflow c++ api undefined reference to 'tflite::D efaultErrorReporter()'
- VSCode C/C++ Intellisense issue: Undefined identifiers (Linu
- 与卡特琳娜一起卷曲C++失败并得到"Undefined symbols for architecture x86_64"
- "Undefined symbols for architecture x86_64" 在 SDL 2 (macOS) 中
- 为什么在使用 SDL2 时仍然收到'undefined reference'链接器错误?
- 从 C 可执行文件加载动态库时收到错误C++"undefined symbol"
- 为什么即使在定义之后仍存在"Identifier is undefined error "?
- OpenCV undefined reference to 'cv::imread(cv::String const&, int)'
- 为什么当我在 C 程序中链接静态库时会"undefined symbol"?
- Vector, assign() function Undefined Behavior
- OpenCV imwrite 函数导致'undefined symbol'
- Libcurl c++ "undefined reference to" (Windows/MinGW/g++)
- 'undefined behaviour'为什么存在?
- "undefined behaviour"扩展到编译时吗?
- 为什么删除不完整的类型定义为"undefined behaviour"?