为什么编译器会抱怨对齐? [英] Why does the compiler complain about the alignment?

查看:58
本文介绍了为什么编译器会抱怨对齐?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解更多关于对齐的信息.为什么 Microsoft 编译器 (Visual Studio 2012 Express) 会抱怨以下代码片段的对齐方式?

I'd like to understand more about alignment. Why does the Microsoft compiler (Visual Studio 2012 Express) complain about the alignment for the following snippet of code?

__declspec(align(16)) class Foo
{
public:
    virtual ~Foo() {}
    virtual void bar() = 0;
};

这是编译器给我的警告:

This is the warning the compiler presents to me:

warning C4324: 'Foo' : structure was padded due to __declspec(align())

这个类是否有任何虚方法都没有关系.即使对于空类,编译器也会发出相同的警告消息.空类是如何对齐的?编译器如何填充这个类?

It does not even matter whether or not the class has any virtual methods. Even for an empty class the compiler complains with the same warning message. How is an empty class aligned? How does the compiler pad this class?

推荐答案

警告并不一定意味着您做错了什么,而是告诉您您可能无意出现这种行为.请注意,允许编译器对开发人员认为值得警告的任何内容发出警告.原则上,您也可能会收到关于在 13 日星期五编译的警告.

A warning does not necessarily mean you've done something wrong, but tells you that you might not have intended this behaviour. Note that a compiler is allowed to warn about anything the developers considered worth warning about. In principle, you could also be warned about compiling on Friday the 13th.

在这种特定情况下,假设可能是当您指定对齐方式时,您不想让类变大.因此,如果由于您给出的对齐要求而使类变大,那么您犯错的可能性不大.

In this specific case the assumption probably is that when you specify alignment, you don't want to make the class bigger. Therefore if the class gets bigger due to the alignment requirement you gave, it's not unlikely that you made a mistake.

当然,这留下了为什么对齐要求使类更大的问题.现在我们又回到了标准领域(尽管 __declspec 本身是 Microsoft 扩展而不是标准).C++ 标准要求在数组中,对象彼此跟随,中间没有任何空间.因此,如果您的对象必须与 16 字节边界对齐,则该对象的大小必须是 16 的倍数.如果成员(显式和隐式)的大小没有给出必要的大小,编译器必须向对象添加未使用的字节.这些字节称为填充.请注意,即使在不是数组成员的对象中也存在此填充.

Of course that leaves the question why the alignment requirement makes the class bigger. Now we are back in standards land (although the __declspec itself is a Microsoft extension and not standard). The C++ standard requires that in arrays, the objects follow each other without any space in between. Therefore if your objects must be aligned to 16-byte boundaries, the object must have a size which is a multiple of 16. If the size of the members (both explicit and implicit) doesn't give the necessary size, the compiler has to add unused bytes to the object. These bytes are called padding. Note that this padding is present even in objects which are not members of arrays.

现在你的类只包含一个隐式虚拟指针(因为它包含虚拟函数),根据架构,它可能是 4 或 8 字节大.由于您已请求 16 字节对齐,因此编译器必须添加 12 或 8 个字节的填充以使大小达到 16 的倍数,如果没有手动对齐规范,则不必添加.这就是编译器警告的内容.

Now your class only contains an implicit virtual pointer (because it contains virtual functions) which, depending on the architecture, probably is either 4 or 8 bytes large. Since you've requested 16 byte alignment, the compiler has to add 12 or 8 bytes of padding to get the size to a multiple of 16, which it would not have had to add without that manual alignment specification. And this is what the compiler warns about.

这篇关于为什么编译器会抱怨对齐?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆