gpt4 book ai didi

c++ - 在C++类成员函数上使用#ifdef防护措施是否安全?

转载 作者:行者123 更新时间:2023-12-03 10:03:21 26 4
gpt4 key购买 nike

假设您具有C++类的以下定义:

class A {
// Methods
#ifdef X
// Hidden methods in some translation units
#endif
};
这是否违反了类(class)的“一个定义规则”?有哪些相关危害?
我怀疑如果使用成员函数指针或虚函数,这很可能会中断。否则使用安全吗?
我在Objective C++的上下文中考虑它。头文件包含在纯C++和Objective C++转换单元中。我的想法是通过OBJC宏来保护带有Objective-C类型的方法。否则,我必须对 header 中的所有Objective-C类型使用void指针,但是这样一来,我将失去强类型,并且必须在整个代码中添加难看的静态强制类型转换。

最佳答案

是的,如果允许单独的编译单元具有不同的宏定义X状态,则可能有违反ODR的危险。在每次包含该类定义以使程序满足合规性要求之前,应在程序(和共享对象)之间全局定义(或不​​定义)X。就C++编译器(不是预处理器)而言,它们是两种不同的,不兼容的,不相关的类类型。
想象一下这样一种情况,在编译单元A.cpp X中定义了class A之前,而在B.cpp X中未定义。如果B.cpp中没有任何东西使用那些被“删除”的成员,则不会得到任何编译器错误。可以认为这两个单元的格式正确。现在,如果B.cpp将包含一个新表达式,它将创建一个不兼容类型的对象,该对象小于A.cpp中定义的对象。但是class A中的任何方法(包括构造函数)在用B.cpp中创建的对象调用时,都可能通过访问对象存储之外的内存来导致UB,因为它们使用较大的定义。
这种愚蠢的变化是,将头文件的副本包含到两个或更多个不同的构建树文件夹中,这些文件夹具有相同的文件名和POD结构类型,这些文件夹之一可通过#include <filename>访问。带有#include "filename"的单元旨在使用替代项。但是他们不会。因为在这种情况下头文件的查找顺序是平台定义的,所以程序员并不完全通过#include "filename"来控制哪个头将包含在每个平台上的哪个单元中。一旦更改了一个定义,甚至仅通过重新排序成员,ODR就被违反。
为了特别安全,此类操作仅应在使用模板,PIMPL等的编译器域中完成。对于跨语言通信,应使用包装程序或适配器来安排一些中间立场,C++和ObjectiveC++可能具有不兼容的内存布局。 POD对象。

关于c++ - 在C++类成员函数上使用#ifdef防护措施是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66040598/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com