Вы return
вводите значение int sum
, устанавливая для него адрес void *
. В этом случае адрес недействителен. Но, если вы помните об этом и получите значение sum
, приведя void *
к int
, это будет работать.
void *
используется таким образом иногда для return
либо значения (например, int
), либо адреса чего-либо (например, struct
).
Чтобы проиллюстрировать это:
int a = 5;
void *p = (void *)a;
int b = (int)p;
a
, p
и b
имеют значение 5
. p
не указывает на действительный адрес. Попытка разыменования p
приведет к неопределенному поведению:
b = *(int *)p; // Undefined Behavior!
Рассмотрим следующую программу:
#include <limits.h>
#include <stdio.h>
int main(void)
{
int a, b;
void *p;
a = 5;
p = (void *)a;
b = (int)p;
printf("%d %p %d\n", a, p, b);
a = INT_MAX;
p = (void *)a + 1;
b = (int)p;
printf("%d %p %d\n", a, p, b);
return 0;
}
При компиляции я получаю следующие предупреждения:
$ gcc main.c -o main.exe
main.c: In function ‘main’:
main.c:9:9: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
p = (void *)a;
^
main.c:10:9: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
b = (int)p;
...
Предупреждение выдается, потому что, как указал @Gerhardh, sizeof(int)
и sizeof(void *)
могут различаться. Вы можете потерять данные, если значение void *
превышает максимальное значение, которое может удерживать int
.
выход
$ ./main.exe
5 0x5 5
2147483647 0x80000000 -2147483648