rav*_*ang 14 c++ gcc language-lawyer
下面的代码可以在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;
}
Run Code Online (Sandbox Code Playgroud)
使用MSC构建的文件输出:
sizeof(A): 4, test.a: -1.
Run Code Online (Sandbox Code Playgroud)
但在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;
^
Run Code Online (Sandbox Code Playgroud)
这是海湾合作委员会的一个错误吗?
感谢您的评论,我只是理解这个问题可能对C无效; 但对于C++部分,我仍然有顾虑.我个人喜欢Visual C++编译行为,它可以在我的场景中节省大量的代码
P.P*_*.P. 28
类型说明符是没有标记的结构说明符的未命名成员称为匿名结构; 一个未命名的成员,其类型说明符是一个没有标记的联合说明符,称为匿名联合.匿名结构或联合的成员被视为包含结构或联合的成员.如果包含的结构或联合也是匿名的,则递归应用.
(强调我的)
基于此,它基本上就像你有:
union A
{
int a:1;
int b:2;
int c1:29;
int a:1;
int b:2;
int c2:28;
int d:1;
int val;
};
Run Code Online (Sandbox Code Playgroud)
这显然是无效的,gcc正确地发出诊断信息.
Bat*_*eba 19
这不是GCC中的错误.
语言标准不允许这样做.但是,如果允许编译Windows头文件,Visual C++会这样做.实际上,如果您不想使用Microsoft编译器来编译Windows标头,那么您需要使用
#define NONAMELESSUNION
Run Code Online (Sandbox Code Playgroud)
之前#include <windows.h>.这在当时似乎是个好主意.
参考:什么是匿名结构,更重要的是,如何告诉windows.h停止使用它们?
PP 的回答和评论中已经讨论过,您想要的不正确,而 GCC 的行为正确。但是满足您的需求的一个简单的解决方法可能是您在第二个结构中重命名aand :b
union A {
struct {
int a:1;
int b:2;
int c1:29;
}PACKED;
struct {
int unused_name_a:1;
int unused_name_b:2;
int c2:28;
int d:1;
}PACKED;
int val;
}PACKED;
Run Code Online (Sandbox Code Playgroud)
这对我在 GCC 和 Clang 中有用,并且应该仍然可以让你的技巧很好地发挥作用。
| 归档时间: |
|
| 查看次数: |
2925 次 |
| 最近记录: |