精华内容
下载资源
问答
  • 编译器字节对齐问题

    2018-04-19 10:44:27
    http://blog.sina.com.cn/s/blog_8b08096f0101amkd.html...一般地,可以通过下面的方法来改变缺省的对界条件: · 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。 · 使用伪指令#pragma pack (),...
    

    http://blog.sina.com.cn/s/blog_8b08096f0101amkd.html

    更改C编译器的缺省字节对齐方式


    在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:


         · 使用伪指令#pragma pack (n),C编译器将按照n个字节对齐。


         · 使用伪指令#pragma pack (),取消自定义字节对齐方式。



     



    另外,还有如下的一种方式:


         · __attribute((aligned (n))),让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。


         · __attribute__ ((packed)),取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。


    【转载例文】


    1. 概述
        本文讨论了结构的自然边界对齐,在缺省情况下,c编译器为每一个变量或数据单元按其自然边界对齐条件分配空间。
        但可以通过四种方法来更改C编译器的缺省字节对齐方式,即可以指定边界对齐。
        
        在阅读完本文档后,将会更深入地了解一个结构的sizeof到底应当是多少。

    2. 自然边界对齐
        在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。

        结构字节对齐有以下几个特点:
        1. 对于结构体,编译器会自动进行成员变量的对齐,以提高运算效率。
           缺省情况下,编译器为结构的每个成员按其自然边界对齐( natural alignment)条件分配空间。
           自然边界对齐即为默认对齐方式。

        2. 各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。

        3. 结构整体的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个。

        4. 结构整体长度的计算必须取所用过的所有对齐参数的整数倍,不够补空字节;
           也就是取所用过的所有对齐参数中最大的那个值的整数倍,因为对齐参数都是2的n次方;
           这样在处理数组时可以保证每一项都边界对齐;

        例如,下面的结构各成员空间分配情况:
        struct test
        {
            char  x1;
            short x2;
            float x3;
            char  x4;
        };
        结构的第一个成员x1,其偏移地址为0,占据了第1个字节。
        第二个成员x2为short类型,其起始地址必须2字节边界对齐,因此,编译器在x2和x1之间填充了一个空字节。
        结构的第三个成员x3和第四个成员x4恰好落在其自然边界对齐地址上,在它们前面不需要额外的填充字节。
        在test结构中,成员x3要求4字节边界对齐,是该结构所有成员中要求的最大边界对齐单元,因而test结构的自然边界对齐条件为4字节,编译器在成员x4后面填充了3个空字节。整个结构所占据空间为12字节。

    3. 指定边界对齐 
       在缺省情况下,c编译器为每一个变量或数据单元按其自然边界对齐条件分配空间;但可以通过下面四种方法来更改C编译器的缺省字节对齐方式:

    方法1: 使用#pragma pack
         #pragma pack说明:
         1. pack提供数据声明级别的控制,对定义不起作用;
         2. 调用pack时不指定参数,将恢复C编译器的缺省字节对齐方式,即使用伪指令#pragma pack()将取消自定义字节对齐方式;
         3. 一旦改变数据类型的alignment,直接效果就是占用memory的减少,但是performance可能会下降;
        
        #pragma pack语法详细说明:
        1. show:可选参数;显示当前packing aligment的字节数,以warning message的形式被显示;
        2. push:可选参数;将当前指定的packing alignment数值进行压栈操作,这里的栈是the internal compiler stack,同时设置当前的packing alignment为n;如果n没有指定,则将当前的packing alignment数值压栈;
        3. pop:可选参数;从internal compiler stack中删除最顶端的record;如果没有指定n,则当前栈顶record即为新的packing alignment数值;如果指定了n,则n将成为新的packing aligment数值;如果指定了identifier,则internal compiler stack中的record都将被pop直到identifier被找到,然后pop出identitier,同时设置packing alignment数值为当前栈顶的record;如果指定的identifier并不存在于internal compiler stack,则pop操作被忽略;
        4. identifier:可选参数;当同push一起使用时,赋予当前被压入栈中的record一个名称;当同pop一起使用时,从internal compiler stack中pop出所有的record直到identifier被pop出,如果identifier没有被找到,则忽略pop操作;
        5. n:可选参数;指定packing的数值,以字节为单位;缺省数值是8,合法的数值分别是1、2、4、8、16。

        #pragma pack规定的对齐长度,实际使用的规则是:结构,联合或者类的数据成员,第一个放在偏移为0的地方,以后每个数据成员的对齐,按照#pragma pack指定的数值和这个数据成员自身长度中比较小的值来对齐。
        也就是说,当#pragma pack的值等于或超过所有数据成员长度的时候,这个值的大小将不产生任何效果。
        而结构整体的对齐,则按照结构体中size最大的数据成员和#pragma pack指定值之间较小的值来对齐。

        -------------------------------------------
        例1:
        #pragma pack(2)
        struct TestA
    {
    public:
    int   a; // 第一个成员,放在[0,3]偏移的位置。
    char  b; // 第二个成员sizeof(char)=1,#pragma pack(2), 取小值也就是1,所以这个成员按1字节对齐,放在偏移[4]的位置。
    short c; // 第三个成员sizeof(short)=2, #pragma pack(2),取小值也就是2,所以这个成员按2字节对齐,所以放在偏移[6,7]的位置。
    char  d; // 第四个成员sizeof(short)=1, #pragma pack(2), 取小值也就是1,所以这个成员按1字节对齐,放在[8]的位置。
    };
        #pragma pack()
        struct TestA中size最大的数据成员(4),#pragma pack(2), 取小值也就是2,所以sizeof(TestA)应当按照2来对齐,为10。

        -------------------------------------------
        例2:
        #pragma pack(4)
        struct TestB
    {
    public:
    int   a; // 第一个成员,放在[0,3]偏移的位置。
    char  b; // 第二个成员sizeof(char)=1,#pragma pack(4), 取小值也就是1,所以这个成员按1字节对齐,放在偏移[4]的位置。
    short c; // 第三个成员sizeof(short)=2, #pragma pack(4),取小值也就是2,所以这个成员按2字节对齐,所以放在偏移[6,7]的位置。
    char  d; // 第四个成员sizeof(short)=1, #pragma pack(4), 取小值也就是1,所以这个成员按1字节对齐,放在[8]的位置。
    };
        #pragma pack()
        struct TestB中size最大的数据成员(4),#pragma pack(4),  取小值也就是4,所以sizeof(TestB)应当按照4来对齐,为12。

        -------------------------------------------
        例3:
        #pragma pack(8)
        struct s1
        {
            short a; // 第一个成员,放在[0, 1]偏移的位置。
            long  b; // 第二个成员sizeof(long)=4, #pragma pack(8), 取小值也就是4,所以这个成员按4字节对齐,放在偏移[4~7]的位置。
        };

        struct s2
        {
            char     

    展开全文
  • c编译器字节对齐指令

    2018-12-23 23:26:00
    #pragma pack (n) 作用:C编译器将按照n个字节对齐。#pragma pack ()作用:取消自定义字节对齐方式。 #pragma pack (push,1)作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为1个字节对齐 #pragma pack...

    #pragma pack (n)             作用:C编译器将按照n个字节对齐。
    #pragma pack ()               作用:取消自定义字节对齐方式。


    #pragma  pack (push,1)     作用:是指把原来对齐方式设置压栈,并设新的对齐方式设置为1个字节对齐

    #pragma pack(pop)            作用:恢复对齐状态

    转载于:https://www.cnblogs.com/fisherman-luo/p/10166448.html

    展开全文
  • 要改变编译器默认的字节对齐方式,Linux下可使用一下两种方法: 一: #pragma pack (n) //C编译器将按照n个字节对齐。 #pragma pack () //取消自定义字节对齐方式 例如: #pragma pack(1) //一下...

    要改变编译器默认的字节对齐方式,Linux下可使用一下两种方法:

    一:

    #pragma pack (n)   //C编译器将按照n个字节对齐。
    #pragma pack ()   //取消自定义字节对齐方式


    例如:

    #pragma pack(1) //一下内容按1个字节对齐
    
    struct Test
    
    {
    
        char a;
    
        int b;
    
    }
    
    #pragma pack() //恢复默认



    二:

    __attribute((aligned (n)))      //让所作用的结构成员对齐在n字节自然边界上。如果结构中有成员的长度大于n,则按照最大成员的长度来对齐。

    __attribute__ ((packed))     //取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐。

    例如:

    struct Test1
    
    {
    
        char a;
    
        int b;
    
    }__attribute((aligned (1)));
    
    //此时结构体大小为8(假设int大小为4),因为int的大小大于1,所以a按大小为4算。
    
    struct Test2
    
    {
    
        char a;
    
        int b;
    
    }__attribute((packed));
    
    //此时结构体按实际占用字节数进行对齐,大小为5.


    如有不对的地方,请大家指出。











    展开全文
  • 首先可以肯定的说,肯定和编译器有关,vc编译器和gcc,g++编译器肯定不一样,不说明是什么编译器什么系统下问你结构体长度...并且最后的字节总长度为最宽长度的整数倍,不足补齐(都是按照对齐模数来的) (2)gcc和g+

    首先可以肯定的说,肯定和编译器有关,vc编译器和gcc,g++编译器肯定不一样,不说明是什么编译器什么系统下问你结构体长度就是在耍流氓。

    (1)vc编译器下结构体成员首地址地址必须被该结构体成员长度整除,打个比方,double a的首地址如果为0x06, 那是不行的,再填2个字节将其首地址变为0x08。并且最后的字节总长度为最宽长度的整数倍,不足补齐(都是按照对齐模数来的)

    (2)gcc和g++编译器是按照对齐模数来对齐的,double类型首元素地址如果为0x04,那么它不用再往里填4个字节补齐,因为32位linux系统gcc编译器对齐模数默认为4,如果为64

    位系统gcc编译器对齐模数默认为8.当然g++编译器也一样,还有32位linux gcc编译器对齐模数为1,2,4, 64位linux gcc编译器对齐模数1,2,4,8。程序选择对齐模数应该是找大于结构体成员字节数最大值的对齐模数,不超过对齐模数的最大值(4或8)。同时最后的结构体字节数总和必须是对齐模数的整数倍,不足补齐。

    (3)gcc中如果结构体内有另一个结构体对象,则字节对齐应该是按照不超过结构体内成员最大占用字节数的对齐模数来设置的,如果struct test对齐模数是4,则从是4的整数倍地址作为结构体对象成员首地址就可以了


    说了这么多给了例子


    struct test                        

    {                                                                  

         int a;

         int b;

         double c;

         char d;

    }; 

    test one;

    struct pp

    {

        int m;

        struct test n;

    };

    test two;

    32 位linux gcc编译器 one:20个字节(4+4+8+1+3 ), two:24个字节(4+20)

    64位linux g++编译器  one:24个字节(4+4+8+1+7),two:32个字节(8+24)

    windows vc编译器one:24个字节(4+4+8+1+7),two:(32个字节)(8+24)

    展开全文
  •  这是编译器字节对齐问题,或者说pack的使用问题。我称之为结构类型的字段对齐问题。  在帖子中redleaves详细讲解了这个问题;buptrobin提出了平台的问题,编译器问题的实验数据;之后又引发了对C,C++标准的讨论。...
  • 结构体字节对齐和瑞萨编译器中结构体对齐的设置
  • 编译器对结构在编译过程中会优化对齐,由于编译器的内存对齐,当一个char变量独立存在时,会分配一个int大小的空间,当两个char连续存在时,会给两个char分配一个int大小的空间. class CMemoryTest { int a; char b; int ...
  • 编译器字节对齐

    千次阅读 2010-08-11 00:36:00
    改变编译器默认对齐大小
  • GCC编译器字节对齐

    千次阅读 2019-07-29 23:32:48
    由于在X86(32位机器)平台下,GCC编译器默认按4字节对齐, 如: 结构体4字节对齐,即结构体成员变量所在的内存地址是4的整数倍 可以通过使用gcc中的__attribute__选项来设置指定的对齐大小。 1): __attribute__ (...
  • 这句指令,指定编译器按照n个字节对齐方式来存放数据。这个会影响struct结构体的占用空间。 2、#pragma pack () 使用默认的对齐方式。 3、根据程序需要,在适当的时候使用一种特别的n个字节对齐,然后恢复之前的...
  • ARM编译器4字节对齐

    2013-11-01 17:19:00
    实际上,只用了1个字节,但是为了4字节对齐,只好分配4个字节,所以就会有3个字节浪费。 (2)我们假设在原来基础上增加一个赋初值的char型全局变量,那么系统会在data区原来的4字节中取出一个字节来保存这个新的...
  • 关于编译器字节对齐 (转)

    千次阅读 2019-01-02 08:42:36
    现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问...各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在...
  • 当然变量起始地址是自身所占字节数的整数倍,是默认情况下字节对齐的前提。...总结:gcc编译器和VC编译器字节对齐方式有些许差别,总的来说VC字节对齐要大一些,而GCC字节对齐方式比较省空间。 .
  • 关于编译器4字节对齐方式比较

    千次阅读 2014-09-10 21:18:00
    所谓的字节对齐,就是各种类型的数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这个就是对齐。我们经常听说的对齐在N上,它的含义就是数据的存放起始地址%N==0。具体对齐规则会在下面的篇幅中介绍...
  • linux C 字节对其简介 在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。 在结构中,编译器为...
  • 关于C编译器字节对齐的问题 zz2006-10-06 11:08是看了CSDN上一篇文章,很有感想,把问题总结了一下,找了一些资料,把知识点结合了一下,算一个资源的集合吧.声明:只是为了方便个人学习用:)首先是来自...
  • 以前一直用MDK,用__align(4)就可以定义一个首地址被4整除、地址按4字节对齐的数组,但今天用IAR发现这么写编译报错。 搜了一下才发现,原来不同编译器,需要用不同的表达方式: #if defined (__CC_ARM) /*!&...
  • 字节对齐
  • 在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员 按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。 例如,下面的结构各成员空间分配情况:struct...
  • 通过#pragma pack(n)改变C编译器字节对齐方式document.title="通过#pragma pack(n)改变C编译器字节对齐方式 - "+document.title #pragma pack(8)struct S1{ char a; long b;};struct S2 { char c; struct S1...
  • 在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。  例如,下面的结构各成员空间分配情况: ...
  • 编译器对齐方式

    2018-05-03 00:03:17
    //用来指定结构体(联合)中对齐的字节数,即按多少字节对齐,如果不指定,则结构体按照最大的数据成员的长度进行对齐, //如果指定了,为n,若n大于等于结构体中最大数据成员的长度,则n无效,按照最大数据长度对齐...
  • 关于C编译器字节对齐的问题

    千次阅读 2005-04-20 21:35:00
    同时,说明了更改C编译器的缺省字节对齐方式: 在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。一般地,可以通过下面的方法来改变缺省的对界条件:  · 使用伪指令#pragma pack (n),C...
  • 在看网上的面试题目,遇到位域的问题,其中涉及到字节对齐,答案以及解释和以前自己的理解是不一致的。网上搜索了一下,发现自己理解的实在是太肤浅。。。什么事情能够做到极致精确,真得是不容易啊。做什么事情,当...
  • c编译器内存对齐

    2018-10-29 12:44:39
    现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型数据按照一定的规则在空间...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 51,693
精华内容 20,677
关键字:

不同编译器的字节对齐