巧妙的宏定义
最近在写南京大学的PA2的时候遇到一个比较有趣的宏定义,于是记录了下来。
#define SEXT(x, len) ({ struct { int64_t n : len; } __x = { .n = x }; (uint64_t)__x.n; })
要理解第一部分需要理解:http://www.catb.org/esr/structure-packing/#_bitfields
现在让我们考虑位域(bitfields)。它们使得你能声明比字节宽度更小的成员,低至1位。
struct st{
short s;
char c;
int flip:1;
int nybble:4;
int septet:7;
};
从编译器的角度来看,struct st里的位域就像2字节,16位的字符数组,只用到了12位。为了使结构体的长度是它的最宽成员长度(即sizeof(short))的整数倍,还有一个字节的填充:
struct st{
short s; //2个字节
char c; //1个字节
int flip:1; //总 1 bit
int nybble:4; //总 5 bits
int septet:7; //总 12 bits
int pad:4; //总16 bits
charpad; //1个字节
};
如果你的结构体中含有结构体,里面的结构体也要和最长的标量有相同的对齐。
以int pad2为例,其实就是将其扩展位32bit.
要理解第二部分需要理解:https://blog.csdn.net/lxgwm2008/article/details/7832502
其实就是将n进行初始化位x,而后赋值给_x.
要理解第三部分需要理解:ttps://blog.csdn.net/fly1000fans/article/details/70210419
例子:
#include <stdio.h>
int main()
{
int a = 10;
a = ({ int c = 0; c = 5 + 6;});
printf("a = %d\n", a);
return 0;
}
从上面例子其实就可以很容易理解第三部分了.