art packed 专有词解释

定义编译器字节对齐方式
gcc中,在某个变量x后使用“__attribute__((packed))”可以通知编译器保证字节对齐。
在lwip中包是存储在结构体里,而结构体及其成员可能存在字节不对齐现象,32位/16位CPU不能正确读写这类数据,导致数据包操作错误。

如下图:32位系统中,x为3字节,y为4字节,z为1字节。系统将不能正确读写y。

  31            8 7    0
  ----------------------
  |      x       |  y  |
  ----------------------
  |      y       |  z  |
  ----------------------

改成下图才可以正确访问:

  31            8 7    0
  ----------------------
  |     |      x       |
  ----------------------
  |          y         |
  ----------------------
  |              |  z  |
  ----------------------
可见空间被浪费了,但只有这样x、y、z才可以直接访问,否则,你必须读两次内存(每次32位),再移位操作跨边界的y,才能正确读出y。
编译器缺省时为了节约内存耗费,将按字节紧凑排列变量,用attribute关键字指出packed,就是通知编译器按字独立分配每个变量的内存空间。

编译器加优化可以将上图改变如下:

  31            8 7    0
  ----------------------
  |  z   |      x      |
  ----------------------
  |         y          |
  ----------------------
这样既保证字节对齐,又保证节约内存。

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

class PACKED(4) ImageHeader { }

#define PACKED(x) __attribute__ ((__aligned__(x), __packed__))

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

typedef __packed struct
{
    double dValue1;
    char   u8Value2;
    int    u32Value3;
} ASampleStructor;

上例中,size值为13,说明1字节对齐后,该结构总长为13字节。去掉__packed对齐后,为16字节。

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

我们已经知道,const变量不能被修改。C++还提供了一种更为``严格''的constexpr说明符(constexpr-specifier), 在变量被声明或者定义的时候,如果类型说明符前面或者后面用了constexpr说明符,则表明该变量是一个const变量同时该变量必须被初始化。你也 许说,这个const不是一样么?constexpr更加严格,用来初始化该变量的表达式必须是一个``常数表达式''。也就是说constexpr变量 是一个由常数表达式初始化的const变量。关于常数表达式,我们以后还会详细谈起,对于基本数据类型来说,常数表达式是由字面值常 量,constexpr限制的变量,和由常数表达式初始化过的const变量组成的表达式。换句话说,常数表达式的值在编译期间就可以确定。例如,

int nonconst_var = 100;
const int const_var1 = 2; 
const int const_var2 = nonconst_var; 
constexpr int constexpr_var1 = 3 + const_var1 * 4; //成立
constexpr int constexpr_var2 = 3 + nonconst_var * 4; //错误
constexpr int constexpr_var3 = 3 + const_var2 * 4; //错误

constexpr的变量的值必须是编译器在编译的时候就可以确定的。上例中因为nonconst_var的值在语法上来讲,运行期间可能被更改,所以编 译期间无法确定,不属于常数表达式。因为const_var2是由非常数表达式来初始化的,所以const_var2也不是常数表达式。但 const_var2本身的声明,定义及初始化是合法的。constexpr比const更严格,用来初始化constexpr_var2和 constexpr_var3的也都不是常数表达式,所以他们的定义都是错误的。

 

posted @ 2015-08-22 16:19  牧 天  阅读(247)  评论(0)    收藏  举报