将指针强制转换为整数会在64位arch上发出警告
我正在编写一个linux内核模块,它使用导出的符号将指针强制转换为整数会在64位arch上发出警告,c,pointers,linux-kernel,compiler-warnings,kernel-module,C,Pointers,Linux Kernel,Compiler Warnings,Kernel Module,我正在编写一个linux内核模块,它使用导出的符号open\u exec struct file *open_exec(const char *name) 它返回一个指针,我可以用IS\u ERR宏检查错误: if (IS_ERR(file)) return file; 在编译期间,我收到以下警告: warning: return makes integer from pointer without a cast 这是因为我的函数在这里返回一个整数。如果我试着投下它: return
open\u exec
struct file *open_exec(const char *name)
它返回一个指针,我可以用IS\u ERR
宏检查错误:
if (IS_ERR(file))
return file;
在编译期间,我收到以下警告:
warning: return makes integer from pointer without a cast
这是因为我的函数在这里返回一个整数。如果我试着投下它:
return (int) file;
我在32位机器上没有收到警告,但在64位机器上收到警告:
warning: cast from pointer to integer of different size
这是因为int和指针的大小在32位上相同,但在64位机器上不同
无论是否强制转换,代码似乎都能工作。我只想摆脱这个警告
如何正确地将指针强制转换为整数并获得所需的值,同时不获得编译器警告?我期望的值本质上是linux内核代码库的include/asm generic/errno base.h
中列出的整数
由于我只是在IS_ERR()
为true的情况下将指针视为一个整数,因此我可以确定它实际上只包含一个整数值。您无法正确地将指针强制转换为较小的句点类型。如果确定指针存储的内容,可以进行一些转换
例如,如果您知道一个指针只设置了最低32位,那么您可以强制转换它,并使用一些特定于编译器的pragma来抑制警告。或者,如果您想要散列指针,以便在散列表中使用,您可以将高32位与低32位异或
如果没有更多关于
int
以后如何使用的知识,就无法确定这一点。我不知道您有时想从errno base.h返回一个数字,有时还想返回一个指针——接收函数如何区分这两者?如果相等,那么在Linux GCC上
是32位宽,无论您是在32位还是64位上 linuxint
- 指针在64位体系结构上为64位宽,在64位体系结构上为32位宽 32位体系结构
在32位体系结构上是32位宽,在64位体系结构上是64位宽 架构long
始终为64位宽long-long
long
、long
或void*
——其中void*
是最可移植的
另一种方法是将其记录为偏移量,也就是说,如果您有一个较大的内存区域,您希望将其“强制转换”为32位整数,然后将其转换为类似的值
static struct mybigbuffer *globalbuffer;
int cast2int(void*x)
{
return (int)(globalbuffer-(struct mybigbuffer*)x);
}
然而这只是假设你知道你的内存永远不会超过2^31条globalbuf
记录,并且你的指针保证在边界上对齐等情况下才可以工作。因此,除非你100%确定你知道你在做什么,我也不推荐使用long或void*作为安全选项。linux/ERR.h中的PTR\u ERR()
宏也定义了is\u ERR()
,它将真正是错误代码的指针转换为适当的类型(along
)
您应该使用以下内容:
if (IS_ERR(file))
return PTR_ERR(file);
在源代码中搜索PTR\u ERR()
的现有用法,您将看到这是一种常见模式
函数返回
long
而不是int
,这可能比较合适,但是所有错误代码都应该可以用int
表示,在这里,我要指出一点,我完全确定指针是真的,包含errno-base.han中的一个值,这样做非常好:-D@Corey亨德森:假设你确信int
足够宽。那么我想,(int)(intptr\t)value
就是这样做的。如果警告持续下去,看看如何抑制它。@ Corey Henderson:下面是如何在VisualC++中进行抑制,以便您认为警告是有意义的:如果INT不能保持指针,则代码可能会遇到麻烦;可能不会,但你不能确定;如果函数必须返回指针,为什么要使用int作为返回类型?因为在我返回错误的情况下,95%的情况下我知道错误是什么,并指定它(即return-EPERM;)。对于一个可以出错的函数,它返回一个指针,我想提取错误并报告它;在返回之前“提取”错误,将其映射到int,然后返回该int。。。为什么不呢?或者,在生成它的func中报告错误;无论如何,不要混合整数和指针,即使是32位也是不好的(你怎么能确定地址不匹配-EPERM是偶然的?)看看源代码,用long而不是int可以“解决”问题,而不创建其他的?@Jim ok,抱歉,我的英语有点被否定的概率搞糊涂了:)我不知道内核上下文中提供的类型,但通常在C语言中,指针到整数的转换有[u]intpr\t
的功能。看起来这样就可以了,我甚至不需要强制转换它。谢谢对其他的答案是多么的错误。。。从来没有想过检查API,也没有意识到这一定是一种常见的模式。@Jim:老实说,我一开始误解了真正的问题。如果不考虑在非错误情况下文件
指针发生的情况,则很容易得出结论,即在正常情况下,指针将以int
的形式返回。然后你就被问题的真正含义分散了注意力。