简体   繁体   English

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

[英]Why does a preprocessor directive affect my C++ vector?

I have a class with a block of members that are wrapped in a preprocessor directive:我有一个 class ,其中包含一组包含在预处理器指令中的成员:

class MyClass
{

... 

#ifdef MyConditionalCompilation

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

#endif

...

}

The class also has a member vector std::vector<int> myVector . class 还有一个成员向量std::vector<int> myVector The conundrum is as follows:难题如下:

When I place the vector after the preprocessor block, thusly:当我将向量放在预处理器块之后时,因此:

#ifdef MyConditionalCompilation

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

#endif

std::vector<int> myVector

The vector's address gets... lost?向量的地址……丢失了? Moved?搬家了? during runtime.在运行时。 I can stop at a breakpoint and see members of the vector, as well as its address via &myVector , in certain places of my code, but later during execution the vector has lost its memory address and the objects in the vector are gone.我可以在代码的某些位置停在断点处并通过&myVector查看向量的成员及其地址,但稍后在执行过程中,向量丢失了其 memory 地址,并且向量中的对象消失了。

When I move the vector above the preprocessor block, thusly:当我将向量移动到预处理器块上方时,因此:

std::vector<int> myVector

#ifdef MyConditionalCompilation

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

#endif

I do not experience the same issue.我没有遇到同样的问题。 The vector, its address, and the values I've pushed into it are consistent across runtime.向量、它的地址和我推入其中的值在运行时是一致的。

What on earth is going on here?这到底是怎么回事?

For clarity, MyConditionalCompilation is true, so the code block is included in the class when it's compiled.为清楚起见, MyConditionalCompilation为 true,因此代码块在编译时包含在 class 中。

EDIT: For additional clarity, I've changed the conditional compilation as follows:编辑:为了更加清楚,我将条件编译更改如下:

#define MyConditionalCompilation
#ifdef MyConditionalCompilation

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

#endif

So the code block is absolutely included in both of the test cases described above.因此,代码块绝对包含在上述两个测试用例中。 I've also verified that the instance of the object is the same in example 1, where the vector "vanishes" at runtime.我还验证了 object 的实例与示例 1 中的相同,其中向量在运行时“消失”。

Is your class defined in a header, perhaps?您的 class 是否在 header 中定义? In this case make sure every file that #include s it has MyConditionalCompilation set with the same value as its implementation, because in C and C++ each .cpp / .cc file is compiled as a single, standalone translation unit.在这种情况下,请确保#include的每个文件都将MyConditionalCompilation设置为与其实现相同的值,因为在 C 和 C++ 中,每个.cpp / .cc文件都被编译为单个独立的翻译单元。

Given that you are conditionally adding fields to MyClass its size will change, causing the relative offsets of its member fields to differ.鉴于您有条件地向MyClass添加字段,它的大小会发生变化,导致其成员字段的相对偏移量不同。

An instance allocated in one file compiled without MyConditionalCompilation will have myVector at a different address than one compiled with MyConditionalCompilation set to 1, and passing it to code that assumes it has a different layout will most definitely cause a runtime crash.在未使用MyConditionalCompilation编译的文件中分配的实例的MyConditionalCompilation myVector为 1 编译的文件的地址不同,并且将其传递给假定它具有不同布局的代码肯定会导致运行时崩溃。

A common pattern that is used to avoid this issue is to ship alongside your headers a config.h header containing the configuration values used to build your library.用于避免此问题的常见模式是在您的标头旁边附带一个config.h header,其中包含用于构建您的库的配置值。

Per the recommendations of mcilloni and David Schwartz, I dug into the problem more exhaustively.根据 mcilloni 和 David Schwartz 的建议,我更详尽地研究了这个问题。 The answer was unrelated to the original question, so I'll mark this resolved.答案与原始问题无关,因此我将其标记为已解决。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM