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
映射HashTbl
data
属性
ht->data = mmap(NULL, data_size, prot, MAP_SHARED, file, 0);
ht
类型是 HashTbl
,ht->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
有成员 .data
被 ht->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% 可移植的通用指针。
我正在阅读 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
映射HashTbl
data
属性
ht->data = mmap(NULL, data_size, prot, MAP_SHARED, file, 0);
ht
类型是 HashTbl
,ht->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)
值的长度吗?
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
有成员 .data
被 ht->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% 可移植的通用指针。