【发布时间】:2018-09-13 17:07:01
【问题描述】:
下面的代码可以在Visual C++编译成功。我喜欢它,它很甜!
#include <stdio.h>
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable:4201)
#pragma pack(push,1)
#define PACKED
#else
#define PACKED __attribute__ ((__packed__))
#endif
union A {
struct {
int a:1;
int b:2;
int c1:29;
}PACKED;
struct {
int a:1;
int b:2;
int c2:28;
int d:1;
}PACKED;
int val;
}PACKED;
#ifdef _MSC_VER
#pragma pack(pop)
#pragma warning(pop)
#endif
#undef PACKED
int main(){
A test;
test.val = 0x1078FFF7;
printf("sizeof(A): %d, test.a: %d.\n", sizeof(A), test.a);
return -1;
}
使用 MSC 构建的文件输出:
sizeof(A): 4, test.a: -1.
但是在GCC,包括最新的gcc-7,编译失败,:(
struct.cpp:13:15: error: redeclaration of ‘signed char:1 A::<unnamed struct>::a’
int a:1;
^
struct.cpp:7:15: note: previous declaration ‘signed char:1 A::<unnamed struct>::a’
int a:1;
^
struct.cpp:14:15: error: redeclaration of ‘signed char:2 A::<unnamed struct>::b’
int b:2;
^
struct.cpp:8:15: note: previous declaration ‘signed char:2 A::<unnamed struct>::b’
int b:2;
^
这是 GCC 中的错误吗?
感谢您的cmets,我刚刚明白这个问题可能对C无效;但对于 C++ 部分,我仍然有顾虑。我个人喜欢 Visual C++ 编译行为,它可以在我的场景中节省大量代码
【问题讨论】:
-
您将如何访问您的字段,因为它们在 2 个匿名结构中具有相同的名称?
-
编译器无法区分第一个
a和第二个。 -
我会说是 MSC 中的一个错误让它过去了。
-
C 和 C++ 中重新声明的规则非常不同。在文件范围内,
int c; int c;是有效的 C,无效的 C++。请修正您问题上的标签,只询问您感兴趣的语言。 -
gcc 可能试图尊重 C 标准,MSC 根本不在乎。
标签: c++ gcc language-lawyer