Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将指针强制转换为整数会在64位arch上发出警告_C_Pointers_Linux Kernel_Compiler Warnings_Kernel Module - Fatal编程技术网

将指针强制转换为整数会在64位arch上发出警告

将指针强制转换为整数会在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

我正在编写一个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 (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上

  • int
    是32位宽,无论您是在32位还是64位上 linux
  • 指针在64位体系结构上为64位宽,在64位体系结构上为32位宽 32位体系结构
  • long
    在32位体系结构上是32位宽,在64位体系结构上是64位宽 架构
  • long-long
    始终为64位宽
因此,在64位体系结构上,将指针强制转换为int意味着您将把64位值大小写为32位值,并且您可以在某种程度上确定您将丢失指针的部分64位信息——正如您自己指出的,这就是编译器警告的全部内容

如果您想从指针强制转换为“匿名”,那么您的选择应该是
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()
,它将真正是错误代码的指针转换为适当的类型(a
long

您应该使用以下内容:

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
的形式返回。然后你就被问题的真正含义分散了注意力。