The title nearly says it all, but I will restate the question...
Is the following program a "strictly conforming program" under the C99 standard?
#include <stdlib.h>
/* Removing any pre-existing macro definition, in case one should exist in the implementation.
* Seems to be allowed under 7.1.3 para 3, as malloc does not begin with _X where X is any capital letter.
* And 7.1.4 para 1 explicitly permits #undef of such macros.
*/
#ifdef malloc
#undef malloc
#endif
/* Macro substitution has no impact on the external name malloc
* which remains accessible, e.g., via "(malloc)(s)". Such use of
* macro substitution seems enabled by 7.1.4 para 1, but not specifically
* mentioned otherwise.
*/
void * journalling_malloc(size_t size);
#define malloc(s) ((journalling_malloc)(s))
int main(void)
{
return malloc(10) == NULL ? 1 : 0;
/* Just for the sake of expanding the
* macro one time, return as exit code
* whether the allocation was performed.
*/
}
Let's look at what the C99 standard has to say about it:
See 7.1.3, §1, clause 5:
Each identifier with file scope listed in any of the following subclauses [...] is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.
As you include stdlib.h
, the name malloc
is reserved for use as a macro name.
But 7.1.4, §1 allows using #undef
on reserved names:
The use of
#undef
to remove any macro definition will also ensure that an actual function is referred to.
This makes it possible to re-#define
malloc
, which results in undefined behaviour according to 7.1.3, §2:
If the program [...] defines a reserved identifier as a macro name, the behavior is undefined.
Why does the standard make this restriction? Because other functions of the standard library may be implemented as function-like macros in terms of the original function, so hiding the declaration might break these other functions.
In practice, you should be fine as long as your definition of malloc
satisfies all provisions the standard provides for the library function, which can be achieved by wrapping an actual call to malloc()
.
You will want to change journalling_malloc(...)
from void
to void *
, change the comments to // (because they are commenting out your undef) and add a #endif
near the top, but otherwise it looks fine.
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