【发布时间】:2016-02-24 08:51:07
【问题描述】:
我在看redis的源码。 代码如下:
typedef char *sds;
struct sdshdr {
unsigned int len;
unsigned int free;
char buf[];
};
static inline size_t sdslen(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->len;
}
static inline size_t sdsavail(const sds s) {
struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));
return sh->free;
}
关于这段代码,我有一些问题:
- 为什么
sizeof(struct sdshdr)的输出是8?为什么不包括char buf[]? - 我无法理解函数
size_t sdslen和sdsavail。为什么struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr)));?
【问题讨论】:
-
演员阵容毫无意义。您不能安全地将字符指针转换为结构指针,它违反了严格的别名。此外,将指针隐藏在 typedef 后面是非常糟糕的做法。
-
@Lundin 这就是
(void *)演员修复的内容,对吧?传入指针是char *s,您可以从中减去。然后将结果转换为void *,它可以很好地转换为struct shshdr *(但更短更通用)。 -
@Lundin 我很确定这里没有字符串别名问题,因为指针的值已经改变并且在减法之后指向实际的结构对象。例如,如果字符串本身将被重新解释为结构,但事实并非如此。 Struct 被解释为使用兼容类型的结构。 (char* 也可以指向任何对象。)