简体   繁体   English

如何修复基于cpp具有2种不同大小的C ++结构?

[英]How to fix C++ structs that have 2 different sizes based on cpp?

Let's consider this class in a header file called TestHeader.h 让我们在名为TestHeader.h的头文件中考虑此类

class TestClass
{
public:
    TestClass();

    void DoStuff();
    BOOL v1;
    BOOL v2;
    bool v11;
    char u;
    bool v6;
    static TestClass*   s_pAvatar;
    static BOOL         s_bInputHighlight;

    int v7;
    BOOL v3;
    int v8;
    char t;
    bool v4;
    bool v9[2];
};

Now let's consider 2 cpps, a main.cpp containing this : 现在让我们考虑2个cpps,一个main.cpp包含以下内容:

typedef bool BOOL;

#include "TestHeader.h"

int main()
{
    TestClass C;
    int s1 = sizeof( TestClass );
    int s2 = sizeof( C.v1 );
    void *v1p = &C.v1;
    void *v2p = &C.v2;
    int AddressDiff = ( int )v2p - ( int )v1p;
    C.DoStuff( );

    return 0;
}

And now TestHeader.cpp containing : 现在TestHeader.cpp包含:

typedef int BOOL;

#include "TestHeader.h"

TestClass* TestClass::s_pAvatar = 0;

void TestClass::DoStuff()
{
    int S1 = sizeof(*this);
    int S2 = sizeof(*s_pAvatar);
    void *v1p = &v1;
    void *v2p = &v2;
    int AddressDiff = (int)v2p - (int)v1p;
    int v1size = sizeof(v1);
    if ( S1 != S2 )
    {
    }
}

If you run this sample on both Visual Studio 2013 and Xcode 6.3.1 which is what I tested with, you'll see that the sizeof of the TestClass is different based on what cpp you are currently in. In this case in main.cpp the class is supposedly 24 bytes while in TestHeader.cpp it's 28 due to BOOL being interpreted differently. 如果在我测试过的Visual Studio 2013和Xcode 6.3.1上都运行此示例,您将看到TestClass的sizeof取决于您当前所处的cpp。在这种情况下,在main.cpp中该类据说是24个字节,而在TestHeader.cpp中,它是28个字节,这是因为BOOL的解释不同。

My question is, is this a known C++ issue ? 我的问题是,这是已知的C ++问题吗? Is there any linker flag to check if all structs at least have the same size across all compilation units ? 是否有任何链接程序标志可检查所有编译单元中的所有结构是否至少具有相同的大小?

Note that including header is an inclusion of its text in the relevant translation unit. 请注意,包含标头是将其文本包含在相关翻译单元中。

Thus, the two different translation units get different definitions of the class. 因此,两个不同的翻译单元获得该类的不同定义。

The definitions of the class in various translation units, must be identical. 在各种翻译单元中,类的定义必须相同。 The code therefore has Undefined Behavior, violating the One Definition Rule. 因此,该代码具有未定义行为,这违反了一个定义规则。

The REAL problem here is that you are defining a type BOOL that is different. 这里的实际问题是您要定义的BOOL类型是不同的。 This means that your compiler, doing exactly what you ask it to do, is generating two different structures. 这意味着您的编译器完全按照您的要求进行操作,正在生成两种不同的结构。

It's the old joke of: Patient: "Doctor, it hurts when I do this..." Doctor: "Don't do that then..." 这是一个古老的玩笑:病人:“医生,我这样做会很痛...”医生:“那就别那么做...”

In this case, fix your definition of BOOL so that it is the same in all cases (the simplest way to achieve that is to only ever HAVE one definition, that is in one header file). 在这种情况下,请修正BOOL的定义,使其在所有情况下都相同(最简单的实现方法是只在一个头文件中拥有一个定义)。 There is no simple trick to achieve this, however. 但是,没有简单的技巧可以实现此目的。 It is a case of discipline, code review and understanding what actually gets defined how and where. 这是一种纪律,代码审查并了解实际定义的方式和位置的情况。

[As others have pointed out, this is technically undefined behaviour as it breaks the rule that "you should only have one definition of something that is shared between modules"] [正如其他人指出的那样,这在技术上是未定义的行为,因为它违反了以下规则:“您应该只对模块之间共享的事物定义一个定义”。

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

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