【问题标题】:warning: return makes pointer from integer without a cast but returns integer as desired警告:return 从整数中生成指针而不进行强制转换,但根据需要返回整数
【发布时间】:2013-08-08 03:25:00
【问题描述】:

我正在尝试找出从 C 中的 void * 函数调用返回整数的正确方法。

即..

#include <stdio.h>

void *myfunction() {
 int x = 5;
 return x;
}

int main() {
  printf("%d\n", myfunction());
  return 0;
}

但我不断得到:

警告:return 从整数中生成指针而不进行强制转换

我需要做演员来完成这项工作吗?似乎返回 x 没有问题,真正的 myfunction 返回指向结构和字符串的指针,它们都按预期工作。

【问题讨论】:

  • 你为什么要这样做?
  • myfunction 返回类型为void*,但x 的类型为int。你为什么想让它工作?您正在处理的真正功能是什么?
  • 一个足够好的理由:维护其他人所做的代码。

标签: c function casting integer void


【解决方案1】:

你在这里试图完成什么并不明显,但我假设你正在尝试用 x 做一些指针算术,并希望 x 是这个算术的整数,但返回时是一个 void 指针。无需了解为什么这样做有意义或没有意义,您可以通过将 x 显式转换为 void 指针来消除警告。

void *myfunction() {
 int x = 5;
 return (void *)x;
}

这很可能会引发另一个警告,具体取决于您的系统如何实现指针。您可能需要使用 long 而不是 int。

void *myfunction() {
 long x = 5;
 return (void *)x;
}

【讨论】:

  • 这似乎使警告消失了,我很想知道为什么会这样,或者这是否实际上是未定义的行为。每个人的回答对我来说都是有意义的,但这正是我想要做的。
  • 其他答案假设您想返回一个指向整数的指针,这与将整数作为指针非常不同。你得到的警告是为了确保你意识到你正在把一个 int 变成一个 void 指针。将指针转换为 long 的定义非常明确,尽管通常只使用指针更容易避免混淆。由于 void 指针算术是非法的,请考虑使用 char* 指针,它在算术期间将表现为 int,因为它的大小是一个字节。
  • 可能值得一提的是,可能有一个平台intvoid * 更宽,因此将前者转换为后者会丢失位。因此,如果确实需要将整数存储在指针变量中,可以考虑将整数声明为 intptr_t x;uintptr_t x;,因为 C 标准保证 intptr_tuintptr_t 适合指针变量。跨度>
  • @user2662982:这是明确定义的行为。但是,它可能会丢失位。请参阅我对此的评论。
  • 注意,如果这是你想做的,你也可以写成return (void *) 5;
【解决方案2】:

一个 void * 是一个指向任何东西的指针,你需要返回一个地址。

void * myfunction() {
  int * x = malloc(sizeof(int));
  *x=5;
  return x;
}

话虽如此,您不需要为 int 返回 void *,您应该返回 int * 或者更好的是 int

【讨论】:

  • 我理解您的意图,但C 中没有new 运算符。
  • @Mahesh 哎呀,没注意标签
  • 随便,他可以随时改成malloc(sizeof(int))
  • @JosuéMolina 已修复,无论如何他都应该使用 c++
  • @aaronman 仅供参考Do I cast the result of malloc?
【解决方案3】:

虽然您认为最简单的方法是:

void *myfunction() {
  int x = 5;
  return &x; // wrong
}

这实际上是未定义的行为,因为 x 是在堆栈上分配的,并且当函数返回时堆栈帧被“卷起”。愚蠢但正确的方法是:

void *myfunction() {
  int *x = malloc(sizeof(int));
  *x = 5;
  return x;
}

请永远不要写这样的代码。

【讨论】:

  • 你应该找到一种方法,将整个第一部分变成鲜红色并带有一个 x
  • 我很困惑,为什么我可以在将整数发送到另一个函数时将其转换为 void 指针,但在将整数作为 void 指针时却无法将其转换为返回值?
  • @user2662982 整数存储在堆栈中。当您调用一个函数时,原始函数的“堆栈帧”(变量存储)被保留,新函数在旧堆栈帧的“顶部”获得空间。但是,一旦函数返回,就不能保证变量会被保留,因为“顶部”的空间可以用于其他变量。您可能想阅读有关 stackheap 的更多详细信息。
  • 在第一个代码中,您返回局部变量的地址会导致运行时出现未定义的行为。
  • 使用void* 返回的意图并不是“愚蠢”。可能很愚蠢的是只返回一个整数而不是结构。这种函数通常用作回调的一部分,以便用户的回调可以返回数据指针。
【解决方案4】:

我用gcc -pedantic编译了这个源码:

 #include <stdio.h>

 void *myfunction() {
   size_t x = 5;  
   return (void*)x;
 }

 int main() {
   printf("%d\n", *(int*)myfunction());
   return 0;
 }

没有警告

【讨论】:

    猜你喜欢
    • 2021-07-12
    • 1970-01-01
    • 2021-01-19
    • 2023-02-08
    • 2012-09-22
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多