【发布时间】:2013-06-20 18:44:03
【问题描述】:
这个类是在我的项目中定义的:
class B : public A
{
public:
A& Get_a(int type);
...
protected:
#ifdef COMPILE_FLAG
int line_num;
const char* file_name;
#endif
...
private:
int int_value;
bool bool-val;
};
函数Get_a是这样实现的(我只放了相关部分):
A& B::Get_a(int type)
{
B* returned_a = B->Get_val(type);
return *(A*)(returned_a) ;
}
这是我使用这个类的代码:
{
...
B b_val;
A* a_val = &b_val->Get_a(5);
...
}
我的代码被编译成与 A 类和 B 类编译成的 DLL 不同的 DLL。
我的 DLL 不使用标志 COMPILE_FLAG 编译,但 A、B 的 DLL 确实使用此标志编译。
即使我的代码试图从不同的 B 类转换,我也没有收到任何编译错误。
在我的代码执行期间,a_val 有垃圾字段值;实际上改变了值。
我想解释一下为什么 C++ 编译器没有警告我这个错误,以及如何改进这些 #ifdef 定义的编码提示(我被告知这些字段用于日志记录)。
编辑:如果我要编写 2 个具有相同名称的类,则每个类都在不同的 dll 中。然后,如果我要在它们之间创建一个引用,我会得到一个编译错误。预处理器在编译器之前运行,因此编译器可以检查这个类的重新定义。
【问题讨论】:
-
编译器无法知道用于编译一个 DLL 的标头与用于编译另一个 DLL 的标头不同,或者由加载其中任何一个的客户端代码使用,这就是这里发生的情况。
-
由于
class B类型的定义在两个单独编译的翻译单元中是不同的(程序和DLL是独立的TU,每个TU实际上可能由多个TU组成),您正在调用未定义的行为。编译器、链接器和运行时系统都没有义务提醒您将遇到的问题。您必须确保全局类型class B在程序中的所有位置都相同。
标签: c++