有两个相关的C标准规则:
C99标准,6.3.2.3:
指向void的指针可以转换为指向任何不完整或对象类型的指针.指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针.
而且7.20.1.4:
以下类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针:
uintptr_t
这意味着,以下代码符合:
int *p = NULL;
void *q = (void*)p;
uintptr_t s = (uintptr_t)q;
Run Code Online (Sandbox Code Playgroud)
但它真的需要两步演员吗?如果执行以下操作,编译器是否会执行隐式中间转换:
int *p = NULL;
uintptr_t s = (uintptr_t)p;
Run Code Online (Sandbox Code Playgroud)
(好吧,它可能会出现在大多数编译器上,但我的问题是关于标准符合性)
static char buf[8];
void foo(){
const char* ptr = buf;
/* ... */
char* q = (char*)ptr;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码片段将生成"warning: cast discards ‘__attribute__((const))’ qualifier from pointer target type [-Wcast-qual]".我喜欢,-Wcast-qual因为它可以帮助我不小心写入内存,我不应该写.
但是现在我想抛弃const只出现一次(不是整个文件或项目).它指向的内存是可写的(就像buf上面一样).我宁愿不删除const,ptr因为它在别处使用并且保持指针(一个const和一个非const)似乎是一个更糟糕的主意.