在 mingw 的 gcc-5.3 下具有混合位域和枚举声明的意外 sizeof 结构
Unexpected sizeof struct with mixed bitfields and enum decls under mingw's gcc-5.3
我在使用 mingw gcc 时遇到了一个奇怪的问题,在下面的例子中 sizeof(X)
returns 8 而不是 4:
struct X
{
enum E {e1, e2, e3};
uint32_t v:2;
enum E2 {ee1, ee2, ee3};
uint32_t vv:1;
};
如果我把它改成
struct X
{
enum E {e1, e2, e3};
enum E2 {ee1, ee2, ee3};
uint32_t v:2;
uint32_t vv:1;
};
结果如预期的那样变成了 4。
我知道位域的对齐、排序和其他内容是实现定义的,但是 Linux 下的同一个 gcc 5.3 给出了两个样本的 4。
按照我的观点,枚举声明不能扩大结构的大小并影响位字段包装。那么第一个声明有什么问题?
这是编译命令行:
C:/Qt/Qt5.7.1/Tools/mingw530_32/bin/mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory 'C:/Users/Documents/build-tst-Desktop_Qt_5_7_1_MinGW_32bit-Release'
g++ -c -pipe -fno-keep-inline-dllexport -std=c++1z -std=gnu++1z -O2 -std=gnu++1z -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_SQL_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I..\tst -I. -I..\tst\magic_get\include -Ic://boost_1_62_0 -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtWidgets -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtGui -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtANGLE -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtNetwork -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtSql -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtCore -Irelease -I. -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\mkspecs\win32-g++ -o release\main.o ..\tst\main.cpp
g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o release\tst.exe release/main.o release/mainwindow.o release/moc_mainwindow.o -lmingw32 -LC:\Qt\Qt5.7.1.7\mingw53_32\lib C:\Qt\Qt5.7.1.7\mingw53_32\lib\libqtmain.a -lshell32 -LC:\utils\my_sql\my_sql\lib -LC:\utils\postgresql\pgsql\lib C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Widgets.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Gui.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Network.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Sql.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Core.a
mingw32-make[1]: Leaving directory 'C:/Users/Documents/build-tst-Desktop_Qt_5_7_1_MinGW_32bit-Release'
可在 http://coliru.stacked-crooked.com/a/62d3a09d10fcc648 找到按预期工作的完整示例
不幸的是,我没有找到在线 mingw 以显示意外结果。
看起来它是一个 "feature" 与 MSVC 兼容的 gcc。
https://gcc.gnu.org/onlinedocs/gcc/x86-Variable-Attributes.html
请尝试
1) 添加属性
struct __attribute__((gcc_struct)) X
{
enum E {e1, e2, e3};
uint32_t v:2;
enum E2 {ee1, ee2, ee3};
uint32_t vv:1;
};
2) 添加编译选项-mno-ms-bitfields
我在使用 mingw gcc 时遇到了一个奇怪的问题,在下面的例子中 sizeof(X)
returns 8 而不是 4:
struct X
{
enum E {e1, e2, e3};
uint32_t v:2;
enum E2 {ee1, ee2, ee3};
uint32_t vv:1;
};
如果我把它改成
struct X
{
enum E {e1, e2, e3};
enum E2 {ee1, ee2, ee3};
uint32_t v:2;
uint32_t vv:1;
};
结果如预期的那样变成了 4。
我知道位域的对齐、排序和其他内容是实现定义的,但是 Linux 下的同一个 gcc 5.3 给出了两个样本的 4。
按照我的观点,枚举声明不能扩大结构的大小并影响位字段包装。那么第一个声明有什么问题?
这是编译命令行:
C:/Qt/Qt5.7.1/Tools/mingw530_32/bin/mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory 'C:/Users/Documents/build-tst-Desktop_Qt_5_7_1_MinGW_32bit-Release'
g++ -c -pipe -fno-keep-inline-dllexport -std=c++1z -std=gnu++1z -O2 -std=gnu++1z -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_SQL_LIB -DQT_CORE_LIB -DQT_NEEDS_QMAIN -I..\tst -I. -I..\tst\magic_get\include -Ic://boost_1_62_0 -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtWidgets -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtGui -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtANGLE -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtNetwork -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtSql -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\include\QtCore -Irelease -I. -I..\..\..\..\Qt\Qt5.7.1.7\mingw53_32\mkspecs\win32-g++ -o release\main.o ..\tst\main.cpp
g++ -Wl,-s -Wl,-subsystem,windows -mthreads -o release\tst.exe release/main.o release/mainwindow.o release/moc_mainwindow.o -lmingw32 -LC:\Qt\Qt5.7.1.7\mingw53_32\lib C:\Qt\Qt5.7.1.7\mingw53_32\lib\libqtmain.a -lshell32 -LC:\utils\my_sql\my_sql\lib -LC:\utils\postgresql\pgsql\lib C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Widgets.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Gui.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Network.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Sql.a C:\Qt\Qt5.7.1.7\mingw53_32\lib\libQt5Core.a
mingw32-make[1]: Leaving directory 'C:/Users/Documents/build-tst-Desktop_Qt_5_7_1_MinGW_32bit-Release'
可在 http://coliru.stacked-crooked.com/a/62d3a09d10fcc648 找到按预期工作的完整示例 不幸的是,我没有找到在线 mingw 以显示意外结果。
看起来它是一个 "feature" 与 MSVC 兼容的 gcc。
https://gcc.gnu.org/onlinedocs/gcc/x86-Variable-Attributes.html
请尝试
1) 添加属性
struct __attribute__((gcc_struct)) X
{
enum E {e1, e2, e3};
uint32_t v:2;
enum E2 {ee1, ee2, ee3};
uint32_t vv:1;
};
2) 添加编译选项-mno-ms-bitfields