C++ 联合数组在 32/64 位上有所不同

C++ Union Array differs in 32/64 bits

我的代码:

union FIELD {
    int n;
    char c;
    const char *s;
    FIELD(){}
    FIELD(int v){ n = v; }
    FIELD(char v){ c = v; }
    FIELD(const char* v){ s = v; }
};

struct SF {
    const char* s0;
    char s1;
    int s2;
    const char* s3;
};

int main() {
    printf("sizeof(long) = %ld\n", sizeof(long));
    printf("now is %d bit\n", sizeof(long) == 8?64:32);

    FIELD arrField[] = {
        FIELD("any 8 words 0 mixed"), FIELD('d'), FIELD(251356), FIELD("edcba")
    };
    SF* sf0 = (SF*)&arrField;

    printf("sf0->s0 = %s, ", sf0->s0);
    printf("sf0->s1 = %c, ", sf0->s1);
    printf("sf0->s2 = %d, ", sf0->s2);
    printf("sf0->s3 = %s\n", sf0->s3);
}

当我使用默认64位执行输出时:

我在CMakeLists.txt中添加编译参数:

set_target_properties(untitled PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")

编译32位程序,然后运行输出:


我的问题是,如何使 64 位程序具有与 32 位程序相同的输出行为?

alignas(FIELD)应用于SF的每个成员变量。

此外,您不能依靠 long 的大小来区分 64 位和 32 位系统。检查指针的大小来执行此操作。在某些 64 位系统上 long 是 32 位。例如我的系统就是这种情况。

此外 %ld 需要一个 long 参数,但是 sizeof 运算符产生 size_t 除了大小上不一定匹配 long 之外,它是无符号的.为了安全起见,您需要在那里添加一个强制转换(或者只使用 std::cout,它会根据 << 运算符的第二个操作数自动选择正确的转换)。

union FIELD {
    int n;
    char c;
    const char* s;
    FIELD() {}
    FIELD(int v) { n = v; }
    FIELD(char v) { c = v; }
    FIELD(const char* v) { s = v; }
};

struct SF {
    alignas(FIELD) const char* s0;
    alignas(FIELD) char s1;
    alignas(FIELD) int s2;
    alignas(FIELD) const char* s3;
};

int main() {
    printf("sizeof(long) = %ld\n", static_cast<long>(sizeof(long)));
    printf("now is %d bit\n", static_cast<int>(sizeof(void*)) * 8);

    FIELD arrField[] = {
        FIELD("any 8 words 0 mixed"), FIELD('d'), FIELD(251356), FIELD("edcba")
    };
    SF* sf0 = (SF*)&arrField;

    printf("sf0->s0 = %s, ", sf0->s0);
    printf("sf0->s1 = %c, ", sf0->s1);
    printf("sf0->s2 = %d, ", sf0->s2);
    printf("sf0->s3 = %s\n", sf0->s3);
}