When I create a method of type int the compiler reserves X number of bits in memory. So how does the see a void type? How many bits/bytes does a void type take up?
I think the assumption you made about how a compiler stores return values might be too generic. What happens with return values is determined by the language, the type, and the hardware.
There might be a 'return register' that could hold the value of the return, so no memory would be taken up. The 'return register' could also just point to some allocated in memory based on the type being returned.
I don't see why a function returning void would ever have allocated memory for the return value.
There is no void type per se in C or C++ (I don't know anything about C#). void * is a typeless pointer.
This might be of some help: http://c-faq.com/ansi/voidparith.html
It's just an undefined pointer type, so the size is the size of any other pointer on the system you're creating it on.
the void type does not take any bits. you cannot declare a variable of type void. this:
void a;
causes a compilation error.
void is just a place holder that means "nothing" a function that returns void returns nothing and a function that takes void as an argument, takes no arguments.
You can however declare a variable of type void*:
void* a;
This simply declares a pointer that can point to anything what so ever. as any pointer, it takes the size of a pointer type, i.e. sizeof(void*) which typically equals 4 in 32 bit systems.
On an x86 architecture (using gcc 3.4.6,) the return value of int functions is stored in the eax register. Floating-point numbers are returned via an XMM register or in ST0. [Edit: Thanks Bastien Leonard!]
Void functions simply don't put anything into eax and return.
#include <stdio.h>
int f1(void)
{
printf("f1\n");
return 9.0f;
}
void f2(void)
{
printf("f2\n");
}
double f3(void)
{
return 10.0;
}
int main(void)
{
int x = f1();
f2();
double y = f3();
return 0;
}
builds with gcc -S to:
main:
pushl %ebp
movl %esp, %ebp
subl $24, %esp
andl $-16, %esp
movl $0, %eax
addl $15, %eax
addl $15, %eax
shrl $4, %eax
sall $4, %eax
subl %eax, %esp
call f1
movl %eax, -4(%ebp)
call f2
call f3
fstpl -16(%ebp)
movl $0, %eax
leave
ret
.size main, .-main
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.4.6"
with f2 defined:
f2:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
subl $12, %esp
pushl $.LC1
call printf
addl $16, %esp
leave
ret
.size f2, .-f2
and f1 defined:
f1:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
subl $12, %esp
pushl $.LC0
call printf
addl $16, %esp
movl $9, %eax
leave
ret
If other people get different code from different versions of gcc, that would be interesting to see XD (Maybe in other situations int functions return on the stack...)
I would imagine that in all implementations, though, a void function simply returns nothing. It either leaves the return registers alone and/or drops nothing on (or into) the stack.
It the function returns void
, the caller doesn't expect any return value and nothing needs to be allocated. void
isn't a real type to be returned, it's more an indication to the compiler that the function returns nothing.
On PC, functions return simple values like int
by placing them in a particular register (eax
); the compiler simply generates the appropriate code to retrieve this value. (And if the function returns void
, then the compiler doesn't generates this kind of code.)
On other architectures, the caller might implicitly pass a parameter pointing to an int
where the return value will be placed.
This kind of low-level stuff isn't specified by the C and C++ standards. It may be specified by another standard, or it may be just a convention.
For C#, I guess that the answer lies in how you get a return value in CIL.