警告 C4121 行为和结构对齐 (Visual Studio 2010)
Warning C4121 behavior & structure alignment (Visual Studio 2010)
让我们考虑下面的声明。(Visual Studio 2010,警告级别4)
#pragma pack(push, 2)
#define PADDING 1 // --- <case 1>
/*
#define PADDING 2 // --- <case 2>
*/
struct foo
{
char a[PADDING];
int b;
};
症状
如果将PADDING设置为<case 1>
,它肯定会生成C4121。但对于<case 2>
,它可以在没有任何警告的情况下编译。这两种情况具有相同的结构布局,"b"的偏移量为2字节
我预期<case 2>
为C4121,因为"b"没有在sizeof(int)
边界的倍数上对齐。(来自MSDN。我找不到2010版本。)
问题
我想知道只有<case 1>
产生C4121是否合理,因为得到的结构布局(对齐)是相同的
我错过了什么重要的东西吗?我应该忽略C4121吗?
PS
事实上,我在遇到过这种情况
- 默认对齐值(8字节)
- 指向未定义(仅向前声明)类(16字节)的成员函数的指针
所以,我认为具体的对齐值并不是重点。我写了上面的示例代码,使事情变得简单。
如果你忽略了这个警告,你必须记住:
当数据不在数据大小倍数的边界上对齐时,性能可能会降低,如果您将代码移植到RISC机器,它将不会编译。
至少,你必须决定是否可以冒险抛出异常。。。
使用#pragma pack()
来解决它是一个很好的方法,但有一个问题:
#pragma pack指令只能用于从项目默认打包中减少结构的打包大小。这会导致库头的互操作性问题,例如,如果将项目打包设置为小于此值,则使用#pragma pack(8)。MSDN文档[5]指出,如果#pragma pack打包大于或等于项目打包,它将被忽略。
因此,永远不应该将项目打包设置为默认值8字节以外的任何值,因为这会破坏库头中使用的#pragma-pack指令,并导致结构之间的二进制不兼容
但也包括:
x86体系结构最初不需要对齐的内存访问,在没有它的情况下仍然可以工作
我建议你避免这个警告,这样会更安全。。。
解决这一问题的方法是颠倒struct
成员的顺序,如下所示:http://msdn.microsoft.com/en-us/library/kabt0ka3%28v=vs.80%29.aspx
编辑:另一个链接解释了什么是数据结构对齐以及随之而来的问题:https://en.wikipedia.org/wiki/Data_structure_alignment(我建议您阅读定义和问题部分)
我认为这可能是编译器的问题:
#pragma pack(push, 2)
struct foo
{
char a[3];
int b;
};
int main()
{
foo f[2];
cout << "sizeof(f) = " << sizeof(f) << endl;
cout << "&f[0] =" << &f[0] << endl;
cout << "&f[1] =" << &f[1] << endl;
cout << "&f[0].b =" << &(f[0].b) << endl;
cout << "&f[1].b =" << &(f[1].b) << endl;
}
对于1和3,我得到警告,对于2没有,尽管对于1和2,地址是相同的。
- Visual Studio 2015:Extern "C" 和 "export" 关键字
- 为cl.exe(Visual Studio代码)指定命令行C++版本
- 试图在visual studio上用C++创建一个桌面应用程序
- 如何在MS Visual Studio 2019中运行QT UI
- 如何使用Visual Studio 2017在C++中为参数化对象数组使用唯一指针
- Visual Studio Code - C++ Debugger 無法啟動
- Visual Studio 2019:插入多个C++风格的单行注释
- Visual Studio Code "undefined reference to `WinMain@16'"
- Visual studio代码重构似乎不起作用(例如,重命名符号-f2)
- Visual Studio中的函数声明和函数定义问题
- 如何指定我希望我的LIB链接到的DLL文件?-Visual Studio 2019
- Visual Studio mkl_link_tool.exe链接错误
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 不同的Visual Studio版本中缺少.dll
- 用Visual Studio在C++中嵌入Julia
- Visual Studio 2017循环自动向量化问题
- 有没有办法在远程设备上打开和编辑visual Studio 2017解决方案
- 尝试使用继承和模板实现CRTP.Visual Studio正在生成编译器错误
- Visual Studio在尝试读取resource.txt文件时崩溃
- Visual Studio 2017 不允许我创建 C++ 专用模板