假设我想将一个 void* 指针移动 4 个字节。是以下等价物:
答:
void* new_address(void* in_ptr) {
intptr_t tmp = (intptr_t)in_ptr;
intptr_t new_address = tmp + 4;
return (void*)new_address;
}
乙:
void* new_address(void* in_ptr) {
char* tmp = (char*)in_ptr;
char* new_address = tmp + 4;
return (void*)new_address;
}
都是定义的行为吗?是一种更受欢迎/接受的惯例吗?还有其他理由使用一个而不是另一个吗?
我们只考虑 64 位系统。如果 intptr_t 不可用,我们可以改用 int64_t。
上下文是一个自定义内存分配器,它需要在将新内存块分配到特定地址之前移动指针(出于对齐目的)。我们还不知道结果指针将指向什么对象,但我们知道我们需要将它移动到特定位置,在上面的示例中是 4 个字节。
最佳答案
Michael Kerrisk在第 1415 页上说,
The C standards make one exception to the rule that pointers of different types need not have the same representation: pointers of the types
char *
andvoid *
are required to have the same internal representation.
所有 C 标准保证 (7.18.1.4) 是您可以将 void*
值转换为 intptr_t
(或 uintptr_t
)并返回再次并以指针的相等值结束。
这里的细微差别是,如果正在使用 void*
,我们将无法应用数学运算(包括 ==
)。
关于c - 是否将指针转换到 intptr_t,对其进行算术运算,然后转换回已定义的行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64861886/