I started to look into glibc (GNU Libc)
to understand how it's written. In malloc.c
, I found a piece of code as follow:
#ifndef void
#define void void
#endif
Can someone please explain to me what this means? Isn't void
always defined?
Thanks
Looking at the git history, it was like this:
/*
Void_t* is the pointer type that malloc should say it returns
*/
#ifndef Void_t
#if (__STD_C || defined(WIN32))
#define Void_t void
#else
#define Void_t char
#endif
#endif /*Void_t*/
This was a workaround for historical [C], which did not have void
and malloc()
returned char *
instead of void
. The code was removed by Ulrich Drepper in 2011. The commit does not seems to be generated by a script or anything automatic, so he must had his intension to define like that.
The commit message does not say anything about void
:
Simplify malloc code
Remove all kinds of unused configuration options and dead code.
I don't know for certain what the reason for the #define void void
is in malloc.c
, but my guess follows:
As Yasushi Shoji mentioned, void
was not always a keyword in C. When it was introduced/standardized, a common workaround to be able to compile code using the new void
keyword with compilers that didn't support it was to define void
as a macro such as:
#define void int /* or maybe #define void char */
that macro definition might be done using the compiler command line instead of via a header so that there wouldn't be a need to ensure that all the translation units included a header that defined the macro.
However, it might also be common for programmers migrating to the new keyword to use sequences of code that looked like:
#ifndef void
#define void int
#endif
for example, you'll see the following bit of code:
/*
* This is a fairly bogus thing to do, but there seems to be no better way for
* compilers that don't understand void pointers.
*/
#ifndef void
#define void char
#endif
in http://buildbot.zope.org/Squid-2.4STABLE6%2B/include/snmp_impl.h?annotate=1.1.1.1&cvsroot=Zope.org
So, my guess is that the #define void void
in malloc.c
is just a way to prevent any such sequences that might exist in the headers it includes from redefining void
, yet still allow it to have been previously defined 'gloablly' (there are only comments in malloc.c
before the #define void void
) in case it was being compiled on a configuration that didn't support void
. In other words, if void
wasn't globally defined as a macro before when malloc.c
was started to be compiled, there was no reason something should define to be something else later on in the compile.
Although void
is a keyword in C, keywords are not defined as preprocessor symbols. The code you quoted ensures that it is also defined as a preprocessor symbol.
I don't know why this would be necessary.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With