在info
结构中打印checksum
字段偏移量的一种解决方案是使用宏typeof
和offsetof
:
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
typedef struct
{
struct {
int a;
} something;
struct {
int a;
int b;
int c[42];
uint32_t checksum;
int padding[10];
} info[2];
// ...
} S;
int main(void)
{
S s;
printf("%lun", offsetof(typeof(s.info[0]), checksum));
return 0;
}
不幸的是,typeof
不是标准的,所以我正在寻找一种更方便的方式来编写上面的例子,而不必从S
外部声明info
。
我为什么要这样做?
我有一个大结构,代表代表信息块的闪存的内容。这些块中的每一个都有一个校验和,我想检查一下:
if (s.info[0].checksum != checksum(s.info[0], offsetof(typeof(s.info[0]), checksum))) {
printf("Oopsn");
}
由于typeof
,书写不便携。
你为什么认为(标准 C 中不存在(typeof
是必需的。如果您给结构体一个标签(information
(,这与offsetof
一起游泳:
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
typedef struct
{
struct {
int a;
} something;
struct information {
int a;
int b;
int c[42];
uint32_t checksum;
int padding[10];
} info[2];
// ...
} S;
int main(void)
{
printf("%zun", offsetof(S, info[0].checksum));
printf("%zun", offsetof(S, info[1].checksum));
printf("%zun", offsetof(struct information, checksum));
printf("%zun", offsetof(S, info[0].checksum) - offsetof(S, info[0].a));
return 0;
}
示例运行:
$ ./a.out
180
400
176
176
顺便说一句,不要为结构的 typedef 而烦恼。他们没用。你不必相信我,但你可以相信彼得·范德林登。
使用指针算法。获取元素的地址,然后从结构的地址中减去该地址。
((unsigned char *) &(s.info[0]).checksum - (unsigned char *) &(s.info[0]))