首页 > 解决方案 > 为什么预处理器指令会影响我的 C++ 向量?

问题描述

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

class MyClass
{

... 

#ifdef MyConditionalCompilation

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

#endif

...

}

该类还有一个成员 vector 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这是真的,因此代码块在编译时包含在类中。

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

#define MyConditionalCompilation
#ifdef MyConditionalCompilation

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

#endif

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

标签: c++vectorc-preprocessor

解决方案


你的类是在标题中定义的吗?在这种情况下,请确保#includeMyConditionalCompilation设置的每个文件都具有与其实现相同的值,因为在 C 和 C++ 中,每个.cpp/.cc文件都被编译为单个独立的翻译单元。

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

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

用于避免此问题的常见模式是在您的标头旁边附带一个config.h标头,其中包含用于构建您的库的配置值。


推荐阅读