Is void
a data type in the C programming language? If so, what type of values can it store? If we have int
, float
, char
, etc., to store values, why is void
needed? And what is the range of void?
-
3It fills no purpose at all, wasn't even part of the original K&R pre-ansi C. Some idiot thought `myFunction() { /* ... */ }` looked way too neat, and just had to add some BS `void myFunction(void) { /* ... */ }` - I'd argue that there's other cleaner options in case you can't stand using `char *`, which was the common way to declare "universal" pointers before void. – Christoffer Bubach Jun 28 '20 at 04:38
-
2@ChristofferBubach but `function(void)` != `function()` in C, because in the former you can put exactly no parameters, while in the latter you can put anything: https://www.geeksforgeeks.org/difference-int-main-int-mainvoid (except in C++, on which both mean the function takes exactly no parameters) – Edw590 Dec 14 '21 at 16:34
-
I have to think any c compiler would be able to quite easily detect parameter usage or external linkage in order to use the most efficient call entry points. A reverse syntax to clearly indicate unknown amount of params with ”…” or a new varargs type would be much cleaner and still allow for automatic detection when declared with just empty brackets. which is basically how new code looks anyway, so why add void as well, are compilers really this shitty at book keeping symbols and their usage? – Christoffer Bubach Dec 21 '21 at 01:23
3 Answers
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.

- 1,193
- 3
- 15
- 22

- 101,701
- 37
- 181
- 258
-
18and since you don't specify what a void pointer points to, you can't perform math on it. The compiler wouldn't know how far to move the pointer to get to the next item in memory. – Aug 15 '10 at 15:53
-
6`void MyRoutine();` is an old-style (K&R C) function declaration deprecated by C99, not a prototype. This should be `void MyRoutine(void);` instead. – Jens Dec 27 '12 at 20:09
-
6@fennec: You can perform arithmetic on `void*` values if you're using gcc, which supports it as an extension by pretending `sizeof (void) == 1`. (I personally consider this unfortunate.) – Keith Thompson Dec 27 '12 at 20:10
-
Er... Strictly speaking, the only context in which `void` acts as a "placeholder keyword" is `(void)` function parameter list declaration. (Despite the fact that we have a type between the `()`, the function still accepts zero parameters.) In all other contexts `void` acts as a genuine *incomplete* data type, e.g. type declaration `struct foo;` will produce a type with the same properties as `void`. For this reason it is not correct to say that `void` is "not a real type" and "just a placeholder keyword". `void` is a "real" type. It just happens to be incomplete. – AnT stands with Russia Dec 27 '12 at 21:34
-
Thank you sir, I've been wondering why my POSIX pthread_create had as last argument a "void *" parameter... It's sort of abstraction isn't it? Like abstract data type in Java, I know it is a pointer but roughly it's same idea isn't it? You accept data but not specifying the EXACT type you can pass. So you parse it into void * and then inside the function you cast it back from void * to whatever you've been using before passing it. – gEdringer Jan 20 '15 at 05:07
-
1
-
3@AnT: An imcomplete struct type doesn't have *all* the same properties as `void`. They're both incomplete types, but for example all pointer-to-struct types have the same representation; `void*` may or may not have the same representation. Also, an incomplete struct type can be completed; `void` cannot. – Keith Thompson Sep 15 '15 at 22:59
-
@Keith Thompson, @AnT, also, a function can be declared as returning void, but not an incomplete type. So, it may be more accurate to say, instead of "`void` is an incomplete type', rather, "incomplete types are a specialized kind of `void`" – James Curran Nov 03 '15 at 22:42
-
And also keep in mind that void also has memory allocation.Sizeof(void)=1 It uses 1 byte memory. – Ujjwal Aryal Jul 19 '17 at 16:30
-
-
-
@UjjwalAryal No, `sizeof (void)` is a constraint violation. A gcc non-standard extension permits pointer arithmetic on `void*`, and it's implemented by *pretending* that `sizeof (void) == 1`. The extension is disabled in standard mode, e.g., `gcc -std=c11 -pedantic-errors`. – Keith Thompson Feb 02 '22 at 04:01
-
@pmor `extern void x;` appears to be legal; both gcc and clang accept it in conforming mode -- which surprised me. It's legal to declare an `extern` object with an incomplete type, for example `extern int arr[];`; the definition must provide a complete type. I suppose `extern void x;` means it's impossible to complete the type. As far as I can tell, it's legal but useless. – Keith Thompson Feb 02 '22 at 04:09
-
@JamesCurran I must have missed your comment back in 2015. No, there's no rule that says a function cannot be declared as returning an incomplete type. A function cannot return an array or function type. I don't think it would be useful to say that "incomplete types are a specialized kind of `void`". – Keith Thompson Feb 02 '22 at 04:12
-
@KeithThompson The core question: are you absolutely sure that it is "useless"? Is there _any_ valid operation on `x` declared as `extern void x;`? – pmor Feb 02 '22 at 13:31
-
@pmor No, I'm not absolutely sure; that's why I wrote "As far as I can tell ...". I can't think of any use for it. If you can, feel free to share. – Keith Thompson Feb 02 '22 at 23:29
-
@KeithThompson Yes, indeed. As far as I see, `(void)x;` is a valid operation (despite of being useless). – pmor Feb 03 '22 at 15:28
-
@KeithThompson `1 ? x : x;` (and similar: e.g. `v ? f1() : x;`) is valid as well. Though some C compilers ICE on it. – pmor Feb 05 '22 at 22:41
-
@pmor A long time I used `#define DebugPrint true ?((void)(NULL)) :printf` That allowed me (in release builds) to write `DebugPrint("%s %d", var1,var2);` and it wouldn't generate any code. (On debug builds, it would use a real function `DebugPrint(char*,...)` ) – James Curran Feb 10 '22 at 23:05
-
-
@KeithThompson FYI: for `extern const void x; const void* p = &x;` both GCC and Clang produce no diagnostics. – pmor Feb 15 '22 at 23:30
-
@KeithThompson Re: "no diagnostics": this is because an expression that designates an object of type `
void` (e.g. `const void`) is lvalue. Also: people [use `extern void`](https://stackoverflow.com/q/27263344/1778275). – pmor Jan 24 '23 at 12:42 -
@pmor The standard says that an lvalue potentially designates an object "with an object type other than **`void`**), but I doubt that the intent was to allow an lvalue of type `const void`. – Keith Thompson Jan 24 '23 at 21:46
-
@KeithThompson I doubt too (e.g. "what is the purpose of lvalues of incomplete object type that cannot be completed?"). However, this is what C11 (as well as C2x) prescribes: "The qualified or unqualified versions of a type are _distinct types_ ...". Example: we can take an address of object of incomplete type `const void`, but we cannot complete such type. Then what is the purpose of allowing to take an address of an object of such type in the first place?... – pmor Jan 25 '23 at 09:23
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, 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.)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.

- 254,901
- 44
- 429
- 631
-
-
4@funky-nd: Looking at this againk I suspect you meant to ask the difference between `int func()` and `int func(void)`. The difference is that the latter is a *prototype*, which specifies that the function takes no arguments. The former is an old-style function declaration, which does not specify what arguments it expects. (There is rarely, if ever, a good reason to use old-style function declarations.) – Keith Thompson Dec 19 '18 at 02:23
The C Standard says that void
is an incomplete type that cannot be completed (unlike other incomplete types that can be completed). This means you cannot apply the sizeof
operator to void
, but you can have a pointer to an incomplete type.

- 69,818
- 15
- 125
- 179
-
Сonsider `extern void x;`. 1) if `x` can be completed "outside of C" (e.g. in asm), then why `&x` is invalid? 2) Is there a valid operation on `x`? – pmor Feb 02 '22 at 02:56
-
@pmor If completion happens "outside of C" that means the compiler is unaware of it. Not `&x` is invalid, `void x` is and everything that follows. As for 2), there should be, e.g. assignment of two `void x` to `void y`, but it can't be since the compiler does not know the size of x and y. – Jens Feb 02 '22 at 06:46
-
I meant "`&x` is invalid _in this case_ (i.e. if `x` is declared as `extern void x;`)". – pmor Feb 02 '22 at 13:28
-
Both Clang and GCC accept `extern const void x; const void* p = &x;` under `-std=c11 -pedantic -Wall -Wextra`. Is this code valid? If no, they why Clang and GCC decided to accept it? – pmor Feb 05 '22 at 23:56
-
@pmor Yes, this code is valid. An expression that designates an object of type `
void` (e.g. `const void`) is lvalue. – pmor Jan 24 '23 at 12:39