结构中的填充机制 [英] padding mechanism in structures

查看:69
本文介绍了结构中的填充机制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

你好,全部!


你能否解释一下''结构'字段的填充是如何制作的?



例如:


struct {

char a1;

int a2;

加倍a3;

} str;


当我检查sizeof str时在GCC编译器中我得到大小的值为

16,这意味着一些字节填充正确吗?


谢谢!


PS。或者,如果有的话,请指向Inet链接。


最诚挚的问候,Roman Mashak。电子邮件: mr*@tusur.ru

Hello, All!

Could you please explain me how is the padding of ''structure'' fields is
made?

For example:

struct {
char a1;
int a2;
double a3;
} str;

When I''m checking "sizeof str" in GCC compiler I get the value of size as
16, it means some bytes are padded right?

Thanks!

PS. Or, point me to Inet link, if there is one.

With best regards, Roman Mashak. E-mail: mr*@tusur.ru

推荐答案

看看这是否有助于样本代码附件



#pragma pack([n])


指定结构的包装对齐和工会会员。结构和联合的

包装对齐是通过/ Zp选项设置整个翻译

单位,而包装对齐设置在数据声明
pragma>
等级。在看到pragma之后,pragma在第一个结构或

联合声明生效; pragma对

定义没有影响。


当你使用#pragma pack(n)时,其中n是1,2,4,8或者16,每个结构后的第一个成员是存储在较小的成员类型或n字节的b $ b边界。如果使用不带参数的#pragma pack,则结构成员

将打包为/ Zp指定的值。默认/ Zp打包大小为

/ Zp8。


编译器还支持以下增强语法:


#pragma pack([[{push | pop},] [identifier,]] [n])


此语法允许您将程序组件合并为一个

翻译单元如果不同的组件使用pack pragma来指定

不同的打包对齐。


每次出现一个包pragma并带有push参数存储内部编译器堆栈上的当前

打包对齐。 pragma'的参数列表

从左到右读取。如果使用推送,则当前包装值为

存储。如果为n提供值,则该值将成为新包装

值。如果您指定了一个标识符,您选择的名称,则标识符

与新的包装值相关联。


每次出现的包编译指示都带有pop参数检索内部编译器堆栈顶部的值,并使该值成为新的包装

alignment。如果使用pop并且内部编译器堆栈为空,则

对齐值是从命令行设置的值并发出警告。

如果使用pop和指定n的值,该值成为新的包装

值。如果使用pop并指定标识符,则会从堆栈中删除存储在

堆栈中的所有值,直到找到匹配的标识符。与标识符关联的

包装值也会从堆栈中移除

以及在推送标识符之前存在的包装值

变为新的包装价值。如果找不到匹配的标识符,则使用从命令行设置的

打包值,并发出一级警告

。默认打包对齐为8.


pack pragma的新增强功能允许您编写

头文件,以确保打包值相同之前和之后

遇到头文件:


/ *文件名:include1.h

* /

#pragma pack(push,enter_include1)

/ *你的包含文件代码...... * /

#pragma pack(pop,enter_include1)

/ * include1.h * /

结束在前面的例子中,当前包值与

标识符enter_include1相关联并被推送,记住,进入标题

文件。头文件末尾的包编译指示会删除头文件中可能发生的所有干预元数值,并删除与enter_include1关联的包

值。因此头文件确保

包值在头文件之前和之后相同。


新功能还允许您使用代码,例如作为头文件,

使用pack pragma设置不同于代码中设置的

包装值的包装对齐:


#pragma pack(push,before_include1)

#include" include1.h"

#pragma pack(pop,before_include1)

In在前面的示例中,您的代码受到保护,不会对include.h中可能出现的

打包值进行任何更改。


see if this helps with sample code attachment
pack
#pragma pack( [ n] )

Specifies packing alignment for structure and union members. Whereas the
packing alignment of structures and unions is set for an entire translation
unit by the /Zp option, the packing alignment is set at the data-declaration
level by the pack pragma. The pragma takes effect at the first structure or
union declaration after the pragma is seen; the pragma has no effect on
definitions.

When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each structure
member after the first is stored on the smaller member type or n-byte
boundaries. If you use #pragma pack without an argument, structure members
are packed to the value specified by /Zp. The default /Zp packing size is
/Zp8.

The compiler also supports the following enhanced syntax:

#pragma pack( [ [ { push | pop}, ] [ identifier, ] ] [ n ] )

This syntax allows you to combine program components into a single
translation unit if the different components use pack pragmas to specify
different packing alignments.

Each occurrence of a pack pragma with a push argument stores the current
packing alignment on an internal compiler stack. The pragma''s argument list
is read from left to right. If you use push, the current packing value is
stored. If you provide a value for n, that value becomes the new packing
value. If you specify an identifier, a name of your choosing, the identifier
is associated with the new packing value.

Each occurrence of a pack pragma with a pop argument retrieves the value at
the top of an internal compiler stack and makes that value the new packing
alignment. If you use pop and the internal compiler stack is empty, the
alignment value is that set from the command-line and a warning is issued.
If you use pop and specify a value for n, that value becomes the new packing
value. If you use pop and specify an identifier, all values stored on the
stack are removed from the stack until a matching identifier is found. The
packing value associated with the identifier is also removed from the stack
and the packing value that existed just before the identifier was pushed
becomes the new packing value. If no matching identifier is found, the
packing value set from the command line is used and a level-one warning is
issued. The default packing alignment is 8.

The new, enhanced functionality of the pack pragma allows you to write
header files that ensure that packing values are the same before and after
the header file is encountered:

/* File name: include1.h
*/
#pragma pack( push, enter_include1 )
/* Your include-file code ... */
#pragma pack( pop, enter_include1 )
/* End of include1.h */
In the previous example, the current pack value is associated with the
identifier enter_include1 and pushed, remembered, on entry to the header
file. The pack pragma at the end of the header file removes all intervening
pack values that may have occurred in the header file and removes the pack
value associated with enter_include1. The header file thus ensures that the
pack value is the same before and after the header file.

The new functionality also allows you to use code, such as header files,
that uses pack pragmas to set packing alignments that differ from the
packing value set in your code:

#pragma pack( push, before_include1 )
#include "include1.h"
#pragma pack( pop, before_include1 )
In the previous example, your code is protected from any changes to the
packing value that might occur in include.h.




Le 15/06/2005 13:53,dans d8***********@relay.tomsk.ru,?* Roman Mashak *?

< mr*@tusur.ru> écrit*:

Le 15/06/2005 13:53, dans d8***********@relay.tomsk.ru, ?*Roman Mashak*?
<mr*@tusur.ru> a écrit*:
大家好!

请您解释一下''结构'字段的填充是如何制作的? ?

例如:

struct {
char a1;
int a2;
double a3;
} str;

当我正在检查sizeof str时在GCC编译器中我得到size的值为
16,这意味着有些字节填充正确吗?

谢谢!

PS。或者,如果有的话,请指向Inet链接。

最诚挚的问候,Roman Mashak。电子邮件: mr*@tusur.ru
Hello, All!

Could you please explain me how is the padding of ''structure'' fields is
made?

For example:

struct {
char a1;
int a2;
double a3;
} str;

When I''m checking "sizeof str" in GCC compiler I get the value of size as
16, it means some bytes are padded right?

Thanks!

PS. Or, point me to Inet link, if there is one.

With best regards, Roman Mashak. E-mail: mr*@tusur.ru




It可能是依赖于架构的(和编译器相关的),但是

可能是双重需要8字节对齐,而int需要4个字节,所以:


A1 xx xx xx

A2 A2 A2 A2

A3 A3 A3 A3

A3 A3 A3 A3



It is probably architecture-dependant (and compiler-dependant), but
probably the double needs 8 bytes alignment, and the int needs 4 bytes, so:

A1 xx xx xx
A2 A2 A2 A2
A3 A3 A3 A3
A3 A3 A3 A3


2005年6月15日星期三14:11:40 +0200,Mehta Shailendrakumar写道:
On Wed, 15 Jun 2005 14:11:40 +0200, Mehta Shailendrakumar wrote:
看看这是否有助于示例代码附件
pack
#pragma pack([n])


请注意,C语言没有定义一个名为

#pragma的预处理程序指令包。你的编译器可能会提供一个作为扩展名,但是你不能认为它会存在于其他编译器中,或者如果它存在,它将以相同的方式在

中运行。

指定结构和联合成员的打包对齐方式。虽然通过/ Zp选项为整个翻译单元设置了结构和联合的包装对齐,但


同样,编译器选项本质上是编译器特定的。你的编译器

可能支持这样一个选项,但你不能假设其他人会这样做。在

特别是原始海报的编译器可能不会。

打包对齐设置在数据声明级别由pack pragma 。 pragma在看到pragma之后的第一个结构或联合声明生效;
编译指示对定义没有影响。


由于这些都不是C语言功能,因此它们并不特别与comp.lang.c相关。另外一个问题是关于填充

的工作原理比你控制它的方式更多。在标准的便携式C中你不能。

当你使用#pragma pack(n)时,其中n是1,2,4,8或16,每个
结构成员在第一个存储在较小的成员类型或
n字节边界之后。如果使用不带参数的#pragma pack,
结构成员将打包到/ Zp指定的值。默认的
/ Zp打包大小为/ Zp8。

编译器还支持以下增强语法:
see if this helps with sample code attachment
pack
#pragma pack( [ n] )
Note that the C language doesn''t define a preprocessor directive called
#pragma pack. You compiler may provide one as an extension but you can''t
assume that it will exist on other compilers or if it does it will act in
the same way.
Specifies packing alignment for structure and union members. Whereas the
packing alignment of structures and unions is set for an entire
translation unit by the /Zp option,
Again, compiler options are inherently compiler specific. Your compiler
might support such an option but you can''t assume that others will. In
particular the original poster''s compiler probably doesn''t.
the packing alignment is set at the
data-declaration level by the pack pragma. The pragma takes effect at
the first structure or union declaration after the pragma is seen; the
pragma has no effect on definitions.
Since neither of these are C language features they aren''t particularly
relevant to comp.lang.c. Also the question was more about how padding
works than how you might control it. In standard, portable C you can''t.
When you use #pragma pack(n), where n is 1, 2, 4, 8, or 16, each
structure member after the first is stored on the smaller member type or
n-byte boundaries. If you use #pragma pack without an argument,
structure members are packed to the value specified by /Zp. The default
/Zp packing size is /Zp8.

The compiler also supports the following enhanced syntax:




再次,你意思是*你的*编译器。通常最好处理的事情

喜欢#pragma pack,因为它们本身就是非常便宜的,所以很好地避开它们。

非便携式。


劳伦斯



Again, you mean *your* compiler. Usually the best thing to do with things
like #pragma pack is avoid them studiously since they are inherently
non-portable.

Lawrence


这篇关于结构中的填充机制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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