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);
}
我的代码:
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);
}