C 中的 mmap、void 指针和类型转换

Mmap, void pointer and type casting in C

我正在阅读 C on disk hash table 代码,但对 C 或 mmap 了解不多,但我知道 Golang。

这段代码让我很困惑。 有两个这样的结构。

typedef struct HashTbl
{
    void *data;
    ...
} HashTbl;
typedef struct Header
{
    char magic[16];
    size_t total;
    size_t used;
} Header;

它使用mmap映射HashTbldata属性

ht->data = mmap(NULL, data_size, prot, MAP_SHARED, file, 0);

ht 类型是 HashTblht->data 将转换为 Header 以设置 属性 值,如下所示:

Header *h = (Header *)ht->data;
strcpy(h->magic, MAGIC_STR);
h->total = 12;
h->used = 0;

然后这个函数:

void *hashtable_of(HashTbl *ht)
{
    return (unsigned char *)ht->data + sizeof(Header);
}

这个函数的用法:

uint64_t *table = (uint64_t *)hashtable_of(ht);

我不明白这个函数的作用是什么,是计算void pointer (Header::data)值的长度吗?

C 中的

void pointer 看起来像 Go 中的 interface{} ,可以转换为任何类型。 但是 Go 在进行类型转换时有错误处理,如果我们将 interface{} 类型转换为错误的类型,它将 return 错误

但是在这个 C 代码中,它转换了一个 Struct -> unsigned char pointer 并将其组合到 sizeof 其他结构,这意味着 unsigned char pointer 是一个整数?!

这怎么可能?

it casts a Struct -> unsigned char pointer and combine it to sizeof other struct, which means unsigned char pointer is an integer?

void *hashtable_of(HashTbl *ht)
{
    return (unsigned char *)ht->data + sizeof(Header);
}

不完全是。代码以一个指针 ht 开始并确定另一个指针 return 指针。

没有一个struct的演员表。有一个 unsigned char *.

的演员表

除了 sizeof(Header) 之外,此代码中没有整数。


让我们一步步来:

指针 ht 有成员 .dataht->data 取消引用。结果是 void *

void * 被转换为 unsigned char 指针。

接下来,代码用... + sizeof(Header)执行指针加法。指针加法与类似整数加法,但有区别。这里添加一个指针和整数会产生另一个 unsigned char 指针,它在内存中更远 sizeof(Header) 字节 (unsigned char)。

最后这个 unsigned char 指针被转换为 void * 作为 return 的一部分。


hashtable_of()没有周围的代码,整体用法不清楚。


void pointer in C seems like interface{} in Go, which could be cast to any type.

差不多。 void 指针可以转换为任何 object 指针,但具有值有效性和对齐限制。 void 指针可能不足以表示 function 指针。 C 缺少 100% 可移植的通用指针。