2

This class was defined in my project:

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;
};

The function Get_a is implemented like this (I put the relevant parts only):

A& B::Get_a(int type)
    {
     B* returned_a = B->Get_val(type);
     return *(A*)(returned_a) ;
    }

This is the code where I use this class:

{
...
B b_val;
A* a_val = &b_val->Get_a(5);
...
}

My code is compiled to a different DLL than the DLL where the classes A and B are compiled to. My DLL doesn't compile with the flag COMPILE_FLAG, but the DLL of A, B does compile with this flag. I didn't get any compile error even though my code is trying to convert from different B classes. During my code execution, a_val had garbage field values; actually shifted values.

I would like some explanations on why the C++ compiler didn't warn me from this bug, and also a coding tip of how to improve these #ifdef definitions (I was informed that these fields are used for logging).

Edit: if i would write 2 classes with the same name, each class in a different dll. Then, if i would create a reference between them, i would get a compile error. The preprocesor runs before the compiler, so the compiler can check this redefinition of a class.

4

3 回答 3

5

#ifdef是一个预处理器指令。预处理作为编译的第一部分执行。只有在预处理之后,正常的 C++ 语法才必须是有效的并且可以被检查。

与您#ifdef一起,您违反了单一定义规则:在不同的翻译单元中有两种不同的类定义B(具有不同的大小)。编译器无法检测到这一点。作为结论,我会说这是您代码中的错误。作为编码提示,我建议使用相同的编译器设置编译所有文件。在这种特殊情况下,我将删除#ifdef.

于 2013-06-18T06:46:34.793 回答
3

我想解释一下为什么 C++ 编译器没有警告我这个错误

编译器应该如何警告你?您编译了两个不同的集合,具有不同的选项。由于类定义发生了变化,由于这些标志,每个二进制文件中的内存分配不同。但是编译器怎么会知道这一点呢?

编译不同的版本是一个完全有效的场景,正确使用它们取决于程序员/用户。

所以你必须在所有 DLL 中重新编译到相同的版本,如果它们要相互定义的话。

于 2013-06-18T06:31:34.170 回答
1

#ifdef不会改变你在哪里使用它。如果COMPILE_FLAG不是这样定义,#define COMPILE_FLAG则不会编译该块。所以,你不能使用这些变量(line_num,file_name),如果你使用它们就会得到。这两行完全被忽略了。因此,您也必须将使用这些变量的代码放入其中#ifdef

于 2013-06-18T06:26:26.010 回答