10

I'm trying to find out the proper way to return an integer from a void * function call within C.

ie ..

#include <stdio.h>

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

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

But I keep getting:

warning: return makes pointer from integer without a cast

Is there a cast I need to do to make this work? It seems to return x without problem, the real myfunction returns pointers to structs and character strings as well which all work as expected.

alk
  • 69,737
  • 10
  • 105
  • 255
user2662982
  • 237
  • 1
  • 2
  • 8

4 Answers4

9

It's not obvious what you're trying to accomplish here, but I'll assume you're trying to do some pointer arithmetic with x, and would like x to be an integer for this arithmetic but a void pointer on return. Without getting into why this does or doesn't make sense, you can eliminate the warning by explicitly casting x to a void pointer.

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

This will most likely raise another warning, depending on how your system implements pointers. You may need to use a long instead of an int.

void *myfunction() {
 long x = 5;
 return (void *)x;
}
user2663103
  • 121
  • 2
  • This does seem to make the warning disappear, and I'd love to know why this works or if this is actually undefined behavior. Everyones answers made sense to me, but this does exactly what I was trying to do. – user2662982 Aug 08 '13 at 04:54
  • The other answers assume you wanted to return a pointer to the integer, which is very different than the integer as a pointer. The warning you were getting was to make sure you realized you were turning an int into a void pointer. Casting a pointer to a long is perfectly well defined, although it often is easier to work only with pointers to avoid confusion. As void pointer arithmetic is illegal, consider using a char* pointer, which will behave as an int during arithmetic, since its size is one byte. – user2663103 Aug 08 '13 at 05:10
  • 1
    It might be worth mentioning that there might be a platform where an `int` is wider then a `void *`, so converting the former to the latter would lose bits. So if storing an integer in a pointer variable is really necessary one might consider declaring the integer as `intptr_t x;` or `uintptr_t x;`, as `intptr_t` and `uintptr_t` are guaranteed by the C standard to fit into a pointer variable. – alk Aug 08 '13 at 06:43
  • @user2662982: This is well defined behaviour. However, it might lose bits. Please see my comment a bove on this. – alk Aug 08 '13 at 06:46
  • Note that if this is what you want to do, you can also write it as `return (void *) 5;`. – 1'' Aug 08 '13 at 12:46
2

A void * is a pointer to anything, you need to return an address.

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

That being said you shouldn't need to return a void * for an int, you should return int * or even better just int

aaronman
  • 18,343
  • 7
  • 63
  • 78
0

Although you'd think the easiest way to do this would be:

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

this is actually undefined behaviour, since x is allocated on the stack, and the stack frame is "rolled up" when the function returns. The silly but correct way is:

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

Please never, ever write code like this, though.

1''
  • 26,823
  • 32
  • 143
  • 200
  • 1
    You should find a way to put the whole first part in bright red with an x through it – aaronman Aug 08 '13 at 03:33
  • I'm confused, why is it that I can cast a integer as a void pointer when sending it to another function, but I can't cast a integer as a void pointer when getting it as a return value? – user2662982 Aug 08 '13 at 04:07
  • @user2662982 The integer is stored on the stack. When you call a function, the original function's "stack frame" (storage for variables) is preserved, and the new function gets space "on top" of the old stack frame. However, once the function returns, there's no guarantee that the variables will be preserved, since the space "on top" could be used for other variables. You might want to read about the *stack* and the *heap* for more detail. – 1'' Aug 08 '13 at 04:14
  • in first code you are returning address of local variable causes Undefined behaviour at runtime. – Grijesh Chauhan Aug 08 '13 at 04:25
  • @GrijeshChauhan Yes, that's what I said. – 1'' Aug 08 '13 at 12:44
  • 1
    That isn't "silly" that is the intention of using a `void*` return. What might be silly is returning just a single integer instead of a structure. This kind of function is often used as part of a callback so that the user's callback can return a data pointer. – Zan Lynx Jan 05 '16 at 15:48
  • Yes, `void *` with structures makes sense but for a single integer you can just return int, unless you're required to return `void *` because it's a callback. – 1'' Jan 05 '16 at 18:27
0

I compiled this source with gcc -pedantic:

 #include <stdio.h>

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

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

There is no warnings

Valeriy
  • 1,365
  • 3
  • 18
  • 45