这个宏返回什么以及如何使用它?

时间:2017-12-14 09:24:48

标签: c struct macros

我有一个问题是要了解如何使用此宏来获取IP标头的长度。我有一个名为framehdr.h的文件,我已将该文件包含在main.c中。 framehdr.h文件中的结构如下所示:

struct ip_hdr {
    unsigned char vhl;     /* Version and header length */
    unsigned char tos;     /* Type of service */
    unsigned short len;    /* Total length */
    unsigned short id;     /* Identification */
    unsigned short off;    /* Fragment offset field */
    unsigned char ttl;     /* Time to live */
    unsigned char p;       /* Protocol */
    unsigned short ip_sum; /* Checksum */
    unsigned int src, dst; /* Source and dest address */
};

我可以通过添加所有尺寸来手动获取lentgh:

unsigned int sizeIP = sizeof(testOne.vhl) + sizeof(testOne.tos)    +
                      sizeof(testOne.len) + sizeof(testOne.id)     + 
                      sizeof(testOne.off) + sizeof(testOne.ttl)    + 
                      sizeof(testOne.p)   + sizeof(testOne.ip_sum) +
                      sizeof(testOne.src) + sizeof(testOne.dst);

但是我想使用看起来像这样的宏来获得大小:

#define IP_HL(ip) ((((ip)->vhl) & 0x0f) * 4)

这个宏回归了什么?它是一个数字,所以我可以将它存储在一个int然后打印它或它是如何工作的?

1 个答案:

答案 0 :(得分:4)

它看起来像vhl(它是一个8位成员,除非你的平台上的CHAR_BIT是一个奇怪的值)用于存储有效4位的版本和其他4位的标题长度。

((ip)->vhl) & 0x0f)提取vhl所指向的struct ip成员的最不重要的4位。

乘以4得到实际长度只是服从那个成员的惯例。

您使用sizeof的方式"手动获取长度"正在对与各个成员的大小总和相对应的标题长度做出假设。以struct使用的序列化技术为中心的成员填充和未记录的约定可能意味着情况并非如此。