【发布时间】:2017-02-23 01:36:37
【问题描述】:
当我尝试将 void * 值分配给 intptr_t 变量时,我似乎无法理解 GCC 编译器警告。具体来说,当我使用-std=c99 -pedantic 编译时,我收到以下关于第 7 行变量z 初始化的警告:
警告:初始化从没有强制转换的指针生成整数 [-Wint-conversion]
这里是源代码:
#include <stdint.h>
int main(void){
unsigned int x = 42;
void *y = &x;
intptr_t z = y; /* warning: initialization makes integer from pointer without a cast [-Wint-conversion] */
return 0;
}
当然,如果我明确地将y 转换为intptr_t,那么警告就会消失。但是,当intptr_t 的全部目的在于转换和操作void * 值时,为什么会出现隐式转换警告。
来自 C99 标准的 7.18.1.4 部分:
以下类型指定一个有符号整数类型,其属性是任何有效的 指向 void 的指针可以转换为这种类型,然后再转换回指向 void 的指针, 结果将等于原始指针:
intptr_t
我是在误解标准,还是在这种情况下 GCC 在其“integer from pointer”检查中过于迂腐?
【问题讨论】:
-
并不过分迂腐。隐式转换只是警告存在的常见错误来源。想想当涉及重载解决方案时它会如何变得痛苦。因此,如果您真的知道自己在做什么,请通过(希望是 c++ 风格的)强制转换来通知编译器。
-
intptr_t是一个普通的整数类型。唯一的保证是它可以保存void *的所有相关信息,其他整数类型不保证。所以警告是正确的。为什么首先要使用整数?通常,对于地址上的低级算术或位操作执行此操作。那么强烈推荐uintptr_t。否则,如果您真的想要一个整数来保存指针,请考虑三次(!)。 -
@StoryTeller:考虑到这是 C99,C++ 风格的演员表是个坏主意。
-
@user2357112:非常糟糕的建议!应该非常认真地对待 C 中的警告!
-
@user2357112:
initptr_t是标准整数类型之一的typedef,与任何其他类型一样,但 5(无符号为 6)标准整数类型除外。编译器有充分的理由不知道intptr_t的附加含义。大多数时候,将指针分配给整数 是 错误(忘记取消引用指针)。如果您也将指针分配给char,编译器也会发出警告。那也是一个整数类型。你认为这个警告也可以忽略?
标签: c pointers gcc c99 gcc-warning