See ISO C99 6.10.3.5 paragraph 2.
A preprocessing directive of the form
# undef identifier new-linecauses the specified identifier no longer to be defined as a macro name. It is ignored if
the specified identifier is not currently defined as a macro name.
Even Visual C++ 6 (which was notorious for bad standards compliance) allows this:
You can also apply the
#undefdirective to an identifier that has no previous definition. This ensures that the identifier is undefined. Macro replacement is not performed within#undefstatements.