Looking to get the fundamentals on where the term "void" comes from, and why it is called void. The intention of the question is to assist someone who has no C experience, and is suddenly looking at a C-based codebase.
-
3This question mix 3 languages... that legacy question should be split into 3 different questions. – Stargateur Apr 19 '18 at 02:33
-
1@Stargateur Why? – user16217248 Jul 07 '23 at 17:36
15 Answers
Basically it means "nothing" or "no type"
There are 3 basic ways that void is used:
Function argument:
int myFunc(void)
-- the function takes nothing.Function return value:
void myFunc(int)
-- the function returns nothingGeneric data pointer:
void* data
-- 'data' is a pointer to data of unknown type, and cannot be dereferenced
Note: the void
in a function argument is optional in C++, so int myFunc()
is exactly the same as int myFunc(void)
, and it is left out completely in C#. It is always required for a return value.

- 29,236
- 5
- 72
- 110

- 23,011
- 10
- 73
- 102
-
7void in the argument list is optional in C++, see http://stackoverflow.com/questions/416345/is-fvoid-deprecated-in-modern-c-and-c – Daniel Earwicker Jun 25 '09 at 10:35
-
1
-
@Earwicker and kjetijor, both good points that I debated on, but my sleepless mind needed help ;) Thanks. – Gerald Jun 25 '09 at 10:43
-
9Not disagreeing, but an additional use of void is in the "cast to void" trick to suppress warnings for unused values. It's a bit of a stretch since it doesn't really correspond with how the compiler interprets things, but you can interpret that to mean "I'm using this value to do nothing". – Steve Jessop Jun 25 '09 at 11:13
-
Another good point. laalto more or less mentions this, so I won't pilfer his answer. – Gerald Jun 25 '09 at 11:41
-
also void is not first class citizen in c#. you could not do this for example Action
. – Sergey Mirvoda Jun 25 '09 at 12:21 -
@Sergey - nor do you need to. More irksome is that you can't do Func
, which is why Action has to exist. – Daniel Earwicker Jun 25 '09 at 12:32 -
23In C++, void in the argument list is optional. However, in C, it is NOT optional: foo() means it takes any number of parameters of any type, whereas foo(void) means it takes zero parameters. – Adam Rosenfield Jun 28 '09 at 05:00
-
Could you also elaborate in your answer what it means when void(0) is used? For example, assert() in Release mode is usually defined as void(0). – Ashwin Nanjappa Sep 08 '09 at 08:42
-
"void = nothing" is an "anti-learning" pattern for understanding memory in C/C++. – Michael Cole Nov 15 '22 at 19:05
I have always taken it to mean absent. Here are four cases in the C language that matches to this use of absent
R f(void)
- Function parameters are absentvoid f(P)
- Return value is absentvoid *p
- Type of what is pointed to is absent(void) p
- Usage of value is absent
Other C descendants use it for other things. The D programming language uses it for cases where an initializer is absent
T t = void;
- initializing value is absent

- 30,738
- 21
- 105
- 131

- 496,577
- 130
- 894
- 1,212
-
4What does `(void)p` do? I did not quite get what you meant by "usage of value is absent." – Yashas Nov 27 '17 at 13:20
-
@Yashas If anyone is also confused about the `(void) var;` statement, I've found detailed answers at https://stackoverflow.com/q/21045615. – Arnie97 May 22 '19 at 10:18
-
Perhaps update for [Rust](https://en.wikipedia.org/wiki/Rust_%28programming_language%29) (if that is relevant)? - as the new contender. – Peter Mortensen Nov 12 '21 at 05:27
There are two ways to use void:
void foo(void);
or
void *bar(void*);
The first indicates that no argument is being passed or that no argument is being returned.
The second tells the compiler that there is no type associated with the data effectively meaning that the you can't make use of the data pointed to until it is cast to a known type.
For example you will see void*
used a lot when you have an interface which calls a function whose parameters can't be known ahead of time.
For example, in the Linux kernel, when deferring work you will set up a function to be run at a latter time by giving it a pointer to the function to be run and a pointer to the data to be passed to the function:
struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data = somedata;
} deferred_work;
Then a kernel thread goes over a list of deferred work and when it gets to this node it effectively executes:
bar(somedata);
Then in bar you have:
void bar(void* mydata) {
int *data = mydata;
/* Do something with data */;
}

- 30,738
- 21
- 105
- 131

- 39,711
- 30
- 131
- 179
It means "no value". You use void
to indicate that a function doesn't return a value or that it has no parameters or both. Pretty much consistent with typical uses of word void in English.

- 167,383
- 100
- 513
- 979
It indicates the absence of a return value in a function.
Some languages have two sorts of subroutines: procedures and functions. Procedures are just a sequence of operations, whereas a function is a sequence of operations that return a result.
In C and its derivatives, the difference between the two is not explicit. Everything is basically a function. The void
keyword indicates that it's not an "actual" function, since it doesn't return a value.

- 30,738
- 21
- 105
- 131

- 28,507
- 14
- 48
- 67
Three usage cases for void:
Function signatures.
void foo(int bar)
does not return a value.int bar(void)
does not take any parameters but this is usually expressed with empty argument list:int bar()
. Usage of the void keyword here corresponds to its meaning in English.Generic top-type pointer
void *
that points to unspecified data and cannot be dereferenced. Here the meaning of void is different from other meanings of void: universal type vs. no type.In casts such as
(void) new Foo(this)
to signify that the return value is deliberately thrown away. Here the keyword usage also matches its meaning in English.
Cases 1 and 2 were already covered by @Gerald but case 3 has not been addressed yet.

- 150,114
- 66
- 286
- 303
Think of void as the "empty structure". Let me explain.
Every function takes a sequence of parameters, where each parameter has a type. In fact, we could package up the parameters into a structure, with the structure slots corresponding to the parameters. This makes every function have exactly one argument. Similarly, functions produce a result, which has a type. It could be a boolean, or it could be float, or it could be a structure, containing an arbitrary set of other typed values. If we want a languge that has multiple return values, it is easy to just insist they be packaged into a structure. In fact, we could always insist that a function returned a structure. Now every function takes exactly one argument, and produces exactly one value.
Now, what happens when I need a function that produces "no" value? Well, consider what I get when I form a struct with 3 slots: it holds 3 values. When I have 2 slots, it holds two values. When it has one slot, one value. And when it has zero slots, it holds... uh, zero values, or "no" value". So, I can think of a function returning void as returning a struct containing no values. You can even decide that "void" is just a synonym for the type represented by the empty structure, rather than a keyword in the language (maybe its just a predefined type :)
Similarly, I can think of a function requiring no values as accepting an empty structure, e.g., "void".
I can even implement my programming language this way. Passing a void value takes up zero bytes, so passing void values is just a special case of passing other values of arbitrary size. This makes it easy for the compiler to treat the "void" result or argument. You probably want a langauge feature that can throw a function result away; in C, if you call the non-void result function foo in the following statement: foo(...); the compiler knows that foo produces a result and simply ignores it. If void is a value, this works perfectly and now "procedures" (which are just an adjective for a function with void result) are just trivial special cases of general functions.
Void* is a bit funnier. I don't think the C designers thought of void in the above way; they just created a keyword. That keyword was available when somebody needed a point to an arbitrary type, thus void* as the idiom in C. It actually works pretty well if you interpret void as an empty structure. A void* pointer is the address of a place where that empty structure has been put.
Casts from void* to T* for other types T, also work out with this perspective. Pointer casts are a complete cheat that work on most common architectures to take advantage of the fact that if a compound type T has an element with subtype S placed physically at the beginning of T in its storage layout, then casting S* to T* and vice versa using the same physical machine address tends to work out, since most machine pointers have a single representation. Replacing the type S by the type void gives exactly the same effect, and thus casting to/from void* works out.
The PARLANSE programming language implements the above ideas pretty closely. We goofed in its design, and didn't pay close attention to "void" as a return type and thus have langauge keywords for procedure. Its mostly just a simple syntax change but its one of things you don't get around to once you get a large body working code in a language.

- 93,541
- 22
- 172
- 341
In C#, you'd use the void keyword to indicate that a method does not return a value:
public void DoSomeWork()
{
// Some work
}

- 30,738
- 21
- 105
- 131

- 10,227
- 10
- 51
- 92
-
4Most people don't realise that void maps to the System.Void structure- http://msdn.microsoft.com/en-us/library/system.void.aspx – RichardOD Jun 25 '09 at 10:23
If you're explaining the concept to a beginner, it might be helpful to use an analogy. The use of void in all these cases is analogous in meaning to a page in a book which has the following words, "This page left intentionally blank." It is to differentiate to the compiler between something which should be flagged as an error, versus a type which is intentionally to be left blank because that is the behavior you want.
It always appears in code where normally you would expect to see a type appear, such as a return type or a pointer type. This is why in C#, void maps to an actual CLR type, System.Void because it is a type in itself.
Some programming languages never developed the concept of void, just like some human cultures never invented the concept of the number zero. Void represents the same advancement in a programming language as the concept of zero represents to human language.

- 39
- 1
- 3
-
Just a note in regards to your last sentence - bear in mind that is only true of statically typed languages. Dynamically typed languages do not need void since their methods may just simply not return anything - the "void" is implied by the lack of anything else being returned. – Mark Embling Jun 29 '09 at 22:11
-
Correction to my last comment - I meant to say last paragraph (not sentence). – Mark Embling Jun 29 '09 at 22:12
I was taught "void" means "nothing" in college - it's a faulty mental model and an anti-learning pattern.
In C/C++ void
means "untyped memory". void
does not mean "nothing". An undefined thing is different than no thing.
For example: MLT video framework returns a void *
for newly allocated memory.
If a C/C++ program leaks void *
memory, it's definitely leaking something.
void *mlt_pool_alloc( int size );
void *mlt_pool_realloc( void *ptr, int size );
void mlt_pool_release( void *release );
The first function returns a void *
type to a newly allocated "raw" memory. Physical memory is just an array of 0/1's. Raw physical memory is also practically meaningless for the compiler and programmer.
The programmer creates meaning when he casts void *
to stuff *
or a stuff array.
Note that we can cast any *
to a void *
, and void *
to any *
.
This let's the programmer write any *
code, but manage any
's memory with void *
code. That's the essential benefit to the design.
// Resize allocated memory
void *mlt_pool_realloc( void *ptr, int size );
This function returns and accepts void *
pointers. This function can be used to expand the size of a previously allocated array.
Reallocating "nothing" to more "nothing" is confusing in a void=nothing mental model.
void mlt_pool_release( void *release );
The final function accepts a void *
and returns void
. The returned void
can't be assigned, which leads to the assumption that void
means nothing.
Returning void
is a language convention and an "overloaded meaning" of void
.
A void *
is a pointer to raw untyped memory.

- 15,473
- 7
- 79
- 96
Void is used only in method signatures. For return types it means the method will not return anything to the calling code. For parameters it means no parameters are passed to the method.
E.g.,
void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}
In C# we can omit the void for parameters and can write the above code as:
void MethodThatReturnsAndTakesVoid()
{
// Method body
}
Void should not be confused with null. Null means for the variable whose address is on stack, and the value on the heap for that address is empty.

- 30,738
- 21
- 105
- 131

- 23,230
- 17
- 71
- 111
void means that you won't be returning any value from the function or method.

- 30,738
- 21
- 105
- 131

- 20,583
- 23
- 77
- 112
Void means no value is required in the return type from a function in all of the three languages.

- 30,738
- 21
- 105
- 131

- 25,572
- 15
- 44
- 47
Void is an incomplete type which, by definition, can't be an lvalue. That means it can't get assigned a value.
So it also can't hold any value.
Void is the equivalent of Visual Basic's Sub.

- 371
- 2
- 6
-
1Only as a return type. I can think of three more uses of void: void arguments (function takes nothing), void pointers (no pointer type specified), and void casts (discard value). – c4757p Jun 25 '09 at 15:18