为什么预处理器指令会影响我的 C++ 向量?

Why does a preprocessor directive affect my C++ vector?

我有一个 class,其中有一个包含在预处理器指令中的成员块:

class MyClass
{

... 

#ifdef MyConditionalCompilation

MyObject myObject;
std::string myString;
uint _myInt;

#endif

...

}

class还有一个成员向量std::vector<int> myVector。谜底如下:

当我将向量 放在 预处理器块之后时,因此:

#ifdef MyConditionalCompilation

MyObject myObject;
std::string myString;
uint _myInt;

#endif

std::vector<int> myVector

向量的地址……丢失了?搬家了吗?在运行时。我可以在代码的某些地方停在断点处并通过 &myVector 查看向量的成员以及它的地址,但是稍后在执行过程中向量丢失了它的内存地址并且向量中的对象是走了。

当我将向量 移动到 预处理器块上方时,因此:

std::vector<int> myVector

#ifdef MyConditionalCompilation

MyObject myObject;
std::string myString;
uint _myInt;

#endif

我没有遇到同样的问题。向量、它的地址和我推入其中的值在整个运行时都是一致的。

这到底是怎么回事?

为清楚起见,MyConditionalCompilation 为真,因此代码块在编译时包含在 class 中。

编辑:为了更加清晰,我将条件编译更改如下:

#define MyConditionalCompilation
#ifdef MyConditionalCompilation

MyObject myObject;
std::string myString;
uint _myInt;

#endif

因此代码块绝对包含在上述两个测试用例中。我还验证了对象的实例与示例 1 中的相同,其中向量在运行时“消失”了。

你的 class 是在 header 中定义的吗?在这种情况下,请确保 #include 的每个文件都设置了 MyConditionalCompilation 与其实现相同的值,因为在 C 和 C++ 中,每个 .cpp/.cc 文件都会被编译作为一个独立的翻译单元。

鉴于您有条件地向 MyClass 添加字段,其大小将发生变化,从而导致其成员字段的相对偏移量不同。

在没有 MyConditionalCompilation 编译的文件中分配的实例将在与 MyConditionalCompilation 设置为 1 的编译文件不同的地址处具有 myVector,并将其传递给假定它的代码具有不同的布局肯定会导致运行时崩溃。

用于避免此问题的一种常见模式是随 header 一起提供 config.h header,其中包含用于构建库的配置值。

根据 mcilloni 和 David Schwartz 的建议,我更详尽地研究了这个问题。答案与原问题无关,所以我将其标记为已解决。