以下是MSDN中的话:
Structure Packing and Alignment
Structure packing interacts with compiler alignment behavior as follows.
- If the packsize is set equal to or greater than the default alignment, the packsize is ignored.
- If the packsize is set smaller than the default alignment, the compiler aligns according to the packsize value.
(上面两点其实意思就是:对齐边界为packsize(1 2 4 8 16)和default alignment(一般为8)中的较小者。)
Thus, if the packsize is set to four, data types having a size of four, eight, or 16 bytes are aligned on addresses that are multiples of four. However, there is no guarantee that data types eight bytes in size (64 bits) are aligned on addresses that are a multiple of eight. The packsize has no effect on data types outside of a structure.
In addition, packing affects the alignment of the entire packed structure. For example, in a structure declared under #pragma pack(1), the alignment of all members are forced to one, regardless of whether they would have been naturally aligned even without packing.
The following techniques set a packsize, in bytes:
- The command-line option /Zp (Struct Member Alignment) sets the packsize to n, in which n can be 1, 2, 4, 8, or 16, and in which 8 is the default.
- The compiler directive #pragma pack([n]) sets the packsize to n, in which n can be 1, 2, 4, 8, or 16. If n is not specified, #pragma pack resets the packsize to its value at the beginning of compilation: either the value specified by /Zp (Struct Member Alignment), or the default, which is 8 on most platforms.
The pragma applies only from the point at which it occurs in the source. For example, the /Zp1 option sets the packsize to 1, which causes the compiler to use no padding within structures. To avoid this problem, turn off structure packing or use the __unaligned keyword when accessing unaligned members of such structures through pointers.
关于预处理指令:#pragma pack(n)在MSDN中针对.net framework1.1中的说法是:
Specifies the value, in bytes, to be used for packing. The default value for n is 8. Valid values are 1, 2, 4, 8, and 16. The alignment of a member will be on a boundary that is either a multiple of n or a multiple of the size of the member, whichever is smaller.
#pragma pack(16)
class MyObject{
public:
int a;
double c;
virtual ~MyObject(){}
virtual out(){}
};
在Windows Xp sp2 (32位) VC++6.0 下 MyObject对象的大小应该是:24. 这里的对齐边界应该是8 (packsize=16,default alignment=8) 存在虚函数因此会有虚函数表指针:4字节,再加上int a:4字节 但是要对齐到边界值8,double:8字节,因此加起来一共是24.
分享到:
相关推荐
紧缩对齐(#pragma pack(n))专题分析 在 C 和 C++ 编程语言中,#pragma pack(n) 指令用于控制结构体成员的对齐方式。对齐是指将结构体成员在内存中的存储位置按照一定的规则调整,以提高内存的使用效率和程序的执行...
#pragma pack(push, n) // 结构体定义 #pragma pack(pop) ``` - `push`:保存当前的对齐设置,以便之后恢复。 - `n`:指定新的对齐值,可以是1、2、4、8等,表示以多少字节对齐。 - `pop`:恢复之前保存的对齐设置...
#pragma pack(n) ``` **示例**: ```c++ #pragma pack(1) // 设置成员对齐为1字节 struct MyStruct { char c; int i; }; #pragma pack() // 恢复默认对齐方式 ``` 这样设置后,`MyStruct` 中的 `int` 成员将紧密...
#pragma pack(n) 这是给编译器用的参数设置,有关结构体字节对齐方式设置, #pragma pack是指定数据在内存中的对齐方式。 #pragma pack (n) 作用:C编译器将按照n个字节对齐。 #pragma pack () 作用:取消自定义...
C++中#include、#pragma的含义 C++ 中的预处理指令是编译器在编译源代码之前执行的一些操作,目的是为了提高代码的可读性、可维护性和执行效率。在这些预处理指令中,`#include` 和 `#pragma` 是两个最常用的指令,...
### #pragma 指令详解 #### 一、概述 `#pragma` 是 C 和 C++ 编译器提供的一种预处理指令,它允许程序员指定特定于编译器的行为,而不影响程序的源代码可移植性。通过 `#pragma` 指令,开发者可以控制诸如内存布局...
## 知识点四:#pragma与编译器兼容性 - 尽管#pragma指令为编译器提供了一种灵活的编译控制方式,但开发者在跨平台开发时需要注意,过多地依赖特定编译器的#pragma指令可能会降低源代码的可移植性。 - 在跨平台项目...
与`#define`, `#include`等其他预处理指令不同,`#pragma`更加灵活,可以用来控制编译器的行为,如关闭警告、指定函数所在的代码段等。 #### 二、`#pragma`指令的格式与特点 `#pragma`指令的一般格式为: ``` #...
#pragma warning(push [, n]) #pragma warning(pop) ``` **应用场景**: 1. **禁用警告**:可以使用`#pragma warning(disable : 4507 34)`来禁用特定的警告信息。 2. **限制警告显示次数**:通过`#pragma warning...
`#pragma warning(push, n)` 保存所有警告信息的现有的警告状态,并且把全局警告等级设定为 `n`。 `#pragma warning(pop)` 向栈中弹出最后一个警告信息,在入栈和出栈之间所作的一切改动取消。 例如: ```c #...
pragma指令简介 一、 message 参数。 1 二、 另一个使用得比较多的#pragma参数是code_seg。格式如: 2 三、 #pragma once (比较常用) 3 四、 #pragma hdrstop表示预编译头文件到此为止,...(8) progma pack(n) 10
8. **`#pragma pack`**: 设置结构体成员的对齐方式,影响内存分配和数据存取效率。 了解并熟练运用`#pragma`指令,能显著提高代码的移植性、效率和可维护性。在编写特定平台的嵌入式软件时,这些工具是不可或缺的...
### #pragma预处理指令详解 在深入探讨C和C++编程的世界中,#pragma指令扮演着一个关键角色,尤其在预处理阶段。虽然它不是语言标准的一部分,而是编译器特性的延伸,但它提供了强大的工具,使开发者能够更精细地...
- `#pragma warning(push[,n])`:保存当前警告状态,可选参数`n`(1-4)设置警告等级; - `#pragma warning(pop)`:恢复之前保存的警告状态。 这种机制非常适合于局部控制警告行为: ```c++ #pragmawarning(push) #...
下面,我们将深入探讨几个常见的 `#pragma` 指令,并详细解释它们的功能与用途。 #### 1. #pragma message 指令 `#pragma message` 指令可以在编译过程中向编译器输出一条信息,这对于调试和源代码管理特别有用。...