我在不了解C或mmap
的情况下在磁盘哈希表代码上读取C,但是我知道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{}
类型转换为错误的类型,则会返回错误
但是在此C代码中,它强制转换为Struct
-> unsigned char pointer
并将其组合为sizeof
其他结构,这意味着unsigned char pointer
是整数?!
那怎么可能?
它强制转换为
Struct
->unsigned char pointer
并将其组合为其他结构的sizeof,这意味着无符号char指针是整数?
void *hashtable_of(HashTbl *ht)
{
return (unsigned char *)ht->data + sizeof(Header);
}
不完全是。代码从一个指针ht
开始并确定另一个指针,即返回指针。
没有强制转换为struct
。强制转换为unsigned char *
。
[sizeof(Header)
之外,此代码中没有整数。
让我们逐步采取它:
ht
具有由.data
取消引用的成员ht->data
。结果为void *
。
void *
被强制转换为unsigned char
指针。接下来,代码使用... + sizeof(Header)
执行指针加法。指针加法是
like
整数加法,但有所不同。这里,将指针和整数相加会导致另一个unsigned char
指针,该指针在内存中更远为sizeof(Header)
个字节(unsigned char
)。最后,此unsigned char
指针作为void *
的一部分转换为return
。hashtable_of()
的整体用法尚不清楚,没有周围的代码。C中的[void pointer
似乎像Go中的interface {},可以转换为任何类型。
几乎。可以将void
指针强制转换为任何
object
指针,但要限制其值的有效性和对齐方式。但是void
指针可能不足以表示function指针。 C缺少100%可移植的通用指针。