The type void has no size; that would be a compilation error. For the same reason you can't do something like:
void n;
EDIT.
To my surprise, doing sizeof(void) actually does compile in GNU C:
$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc -w - && ./a.out
1
However, in C++ it does not:
$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc++ -w - && ./a.out
<stdin>: In function 'int main()':
<stdin>:1: error: invalid application of 'sizeof' to a void type
<stdin>:1: error: 'printf' was not declared in this scope
Answer from reko_t on Stack OverflowThe type void has no size; that would be a compilation error. For the same reason you can't do something like:
void n;
EDIT.
To my surprise, doing sizeof(void) actually does compile in GNU C:
$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc -w - && ./a.out
1
However, in C++ it does not:
$ echo 'int main() { printf("%d", sizeof(void)); }' | gcc -xc++ -w - && ./a.out
<stdin>: In function 'int main()':
<stdin>:1: error: invalid application of 'sizeof' to a void type
<stdin>:1: error: 'printf' was not declared in this scope
If you are using GCC and you are not using compilation flags that remove compiler specific extensions, then sizeof(void) is 1. GCC has a nonstandard extension that does that.
In general, void is a incomplete type, and you cannot use sizeof for incomplete types.
Videos
Void is considered a data type (for organizational purposes), but it is basically a keyword to use as a placeholder where you would put a data type, to represent "no data".
Hence, you can declare a routine which does not return a value as:
void MyRoutine();
But, you cannot declare a variable like this:
void bad_variable;
However, when used as a pointer, then it has a different meaning:
void* vague_pointer;
This declares a pointer, but without specifying which data type it is pointing to.
Yes, void is a type. Whether it's a data type depends on how you define that term; the C standard doesn't.
The standard does define the term "object type". In C99 and earlier; void is not an object type; in C11 and later, it is. In all versions of the standard, void is an incomplete type. What changed in C11 is that incomplete types are now a subset of object types. This is just a change in terminology. (The other kind of type is a function type.)
C99 6.2.6 paragraph 19 says:
The void type comprises an empty set of values; it is an incomplete type that cannot be completed.
The C11 standard changes the wording slightly:
The void type comprises an empty set of values; it is an incomplete object type that cannot be completed.
This reflects C11's change in the definition of "object type" to include incomplete types. It doesn't really change anything about the nature of type void.
The void keyword can also be used in some other contexts:
As the only parameter type in a function prototype, as in
int func(void), it indicates that the function has no parameters. (C++ uses empty parentheses for this, but they mean something else in C (prior to C23).)As the return type of a function, as in
void func(int n), it indicates that the function returns no result.void*is a pointer type that doesn't specify what it points to.
In principle, all of these uses refer to the type void, but you can also think of them as just special syntax that happens to use the same keyword.
Only data pointers. void * can hold any data pointer, but not function pointers.
Here is a C FAQ.
void *'s are only guaranteed to hold object (i.e. data) pointers; it is not portable to convert a function pointer to type void *. (On some machines, function addresses can be very large, bigger than any data pointers.)
As for the first part, yes, different types can have pointers of different sizes:
The value stored in the pointer is an address to memory. If you're on a 32-bit system, that pointer into memory is going to be 32 bits (or four bytes) long. If you're on a 64-bit system, that pointer into memory is going to be 64 bits (or eight bytes) long.
The size of the data that holds the location in memory has nothing to do with the size of the data represented at that location in memory.
As for how a char * differs from a double *, the char * can point to any location, but the double * has to point to something along an eight-byte boundary. Larger data has to be aligned according to the rules of the processor you're on. So, pointers to small data are not generally compatible with pointers to large data (e.g. you shouldn't point a double * pointer to a char * address); but you're save going in the other direction (e.g. you can point a char * pointer to a double * address).
I just began studying C and I cannot, for the life of me, understand void.
I have read and listened to many people say "It does not return a value". Ok? What is a value? Why wouldn't we want to return it? What is the difference between "void main" and "int main"? Can we just use int for everything and ignore void altogether?
In what situations is void used? In what situations is void better? etc. Please help I don't get it at all!