#pragma pack(1)是什么意思?

liu0120 2003-12-07 08:56:50
#pragma pack(1)


#pragma pack()是什么意思?
...全文
328 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
byyyyy 2003-12-07
  • 打赏
  • 举报
回复
pack

#pragma pack([n])

该指令指定结构和联合成员的紧凑对齐。而一个完整的转换单元的结构和联合

的紧凑对齐由/Zp选项设置。紧凑对齐用pace编译指示在数据说明层设置。该编译指示在其出现后的第一个结构或联合说明处生效。该编译指示对定义无效。当你使用#pragma pack(n)时,这里n为1、2、4、8或16。第一个结构成员之后的每个结构成员都被存储在更小的成员类型或n字节界限内。如果你使用无参量的#pragma pack,结构成员被紧凑为以/Zp指定的值。该缺省/Zp紧凑值为/Zp8。

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

#pragma pack([[{push|pop},][标识符,]][n])

若不同的组件使用pack编译指示指定不同的紧凑对齐,这个语法允许你把程序组件组合为一个单独的转换单元。

带push参量的pack编译指示的每次出现将当前的紧凑对齐存储到一个内部编译器堆栈中。编译指示的参量表从左到右读取。如果你使用push,则当前紧凑值被存储起来;如果你给出一个n的值,该值将成为新的紧凑值。若你指定一个标识符,即你选定一个名称,则该标识符将和这个新的的紧凑值联系起来。

带一个pop参量的pack编译指示的每次出现都会检索内部编译器堆栈顶的值,并且使该值为新的紧凑对齐值。如果你使用pop参量且内部编译器堆栈是空的,则紧凑值为命令行给定的值,并且将产生一个警告信息。若你使用pop且指定一个n的值,该值将成为新的紧凑值。

若你使用pop且指定一个标识符,所有存储在堆栈中的值将从栈中删除,直到找到一个匹配的标识符,这个与标识符相关的紧凑值也从栈中移出,并且这个仅在标识符入栈之前存在的紧凑值成为新的紧凑值。如果未找到匹配的标识符,将使用命令行设置的紧凑值,并且将产生一个一级警告。缺省紧凑对齐为8。

pack编译指示的新的增强功能让你编写头文件,确保在遇到该头文件的前后的紧凑值是一样的。

/* File name: include1.h*/

#pragma pack(push,enter_include1)

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

#pragma pack(pop, enter_include1)

/* include1.h结束 */

在上面的例子中,当前紧凑值与标识符enter_include1联系起来,并被压入头文件的项中。头文件末尾的pack编译指示删除所有可能出现在头文件中的干预紧凑值,并且删除与enter_include1相关的紧凑值。因此确保该头文件的前后的紧凑值是相同的。

这种新功能也允许你使用代码,例如头文件,它可以使用pack编译指示设置不同于在你的代码中设置的紧凑值的紧凑对齐:

#pragma pack(push,before_include1)

#include "include1.h"

#pragma pack( pop,before_include1)

在上面的例子中,对于出现在include.h中的紧凑值的任何变化,你的代码是受到保护的。
byyyyy 2003-12-07
  • 打赏
  • 举报
回复
http://www.lzu.edu.cn/netteach/bcyy/newles/VC/Reference/Course03%5CCourse_32.htm
byyyyy 2003-12-07
  • 打赏
  • 举报
回复
第2章 编译指示指令
C和C++的每个实现对它的主机或操作系统都支持一些独有的特征。例如,某些程序须对存放数据的存储器区域进行精确的控制,或必须控制特定函数接受参量的方式。#pragma指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。

语法

#pragma 语言符号字符串

语言符号字符串是给出特有编译器指令和参量的字符序列。数字符号(#)必须是包含编译指示行中的第一个非空白字符。空白字符可分开数字符号(#)和单词pragma。在#pragma之后,可以编写翻译器作为预处理器语言符号分析的任何文本。#pragma的参量从属于宏扩展。

如果编译器找到一个不能识别的编译指示,将发出一个警告,但编译将继续。编译指示可用在条件说明中,以提供新的预处理器功能,或提供定义的实现信息给编译器。C和C++编译器可识别下面的编译指示:

alloc_text comment init_seg* optimize

auto_inline component inline_depth pack

bss_seg data_seg inline_recursion pointers_to_members*

check_stack function intrinsic setlocale

code_seg hdrstop message vtordisp*

const_seg include_alias once warning*

仅被C++编译器支持


--------------------------------------------------------------------------------

C++编译器专有编译指示

以下是C++编译器专有的编译指示指令:

* init_segl

pointers_to_members

* vtordisp

init_seg

C++特殊处

#pragma init-seg({complier/lib/user/ "section-name" [,"func-name"]})该指令指定一个影响启动代码执行顺序的关键字或代码段。由于全局静态对象的初始化可能涉及执行代码,因此必须指定创建对象时定义的一个关键字。在动态连接库(DLL)或需初始化的库中使用init_seg编译指示尤其重要。

init_seg编译指示的选项如下:

complier

该选项保留给Microsoft C运行库初始化。这个组中的对象最先被创建。lib 用于第三方类库供应商的初始化。该组中的对象在complier标志之后,其他标记之前创建。

user

用于任何用户。此组对象最后创建。

section_name

允许初始化段的显示规格。在一个用户指定section-name(段名称)中的对象不能被隐含地创建,但它们的地址可放在以section_name命名的段中。

func_name

指定在程序退出时在exit()地方调用的函数。指定的函数必须与exit函数具有相同的特征:int funcname(void(__cdecl*)(void));

如果你需要延迟初始化过程(例如,在一个DLL中),你可以选择显式地指定该段名称。然后必须为每个静态对象调用构造函数。

C++特殊处结束

pointers_to_members

C++特殊处

#progma pointers_to_members(指针说明,[最一般表示])

该指令指定一个类成员的指针能否在其相关定义之前被说明,且用于控制该指针尺寸和解释该指针需要的代码。你可以把一个pointers_to_members编译指示放入你的源文件中替换/vmx编译器选项。

指针说明参量指定你在一个关联函数定义之前还是之后说明了一个成员的指针。指针说明参量是以下两个符号之一:

参量 说明
full_generality 生成安全、但常常并非最优的代码。如果在关联类定义之前说明任何成员的指针,可使用full_generality。该参量通常使用最一般表示参量指定的指针表示形式。等同于/vmg选项
best_case 为所有成员指针使用最佳情况(best__case)表示生成安全的最优代码。使用该参量是需在定义一个类的成员指针说明之前定义此类。其缺省值为best_case

best_case 为所有成员指针使用最佳情况(best__case)表示生成安全的最优代码。使用该参量是需在定义一个类的成员指针说明之前定义此类。其缺省值为best_case

最一般表示参量说明了在转换单元中,编译器能够安全地引用任何指向类成员的指针的最小指针表示。该参量取如下值之一:

参量 说明
single_inheritance 最一般表示是单继承的,即一个成员函数的指针。对于其中说明了一个指向成员指针的一个类定义,若其继承模式说明为多重的或虚拟的,将导致错误
multiple_inheritance 最一般表示是多重继承的,即一个成员函数的指针。对于其中说明了一个指向成员指针的一个类定义,若其继承模式是虚拟的,将导致错误
vitual_inheritance 最一般表示是虚拟继承,即一个成员函数的指针。该函数不会导致错误。当使用#pragmapointers_to_members(full_generality) 时这是个缺省参量

C++特殊处结束

gushaoping 2003-12-07
  • 打赏
  • 举报
回复

规范,调整结构体的边界对齐.让其已一个字节对齐
step_by_step 2003-12-07
  • 打赏
  • 举报
回复
调整结构体的边界对齐.让其已一个字节对齐

64,646

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧