Re: Is this C?



Duncan Muirhead wrote:
I came across code somewhat like this, and was somewhat
puzzled by it. Is it C, or does gcc just compile it (" gcc -Wall -std=c89 -pedantic odd.c eg.c -o odd")
without complaints?
The idea is to override a function by defining a new function with an extra argument, and a macro.
(The reason was that in the real code the function
being replaced was called many times, and the aim
was to gather more diagnostic information in debugging
without having to change all the calls).

eg.c:
#include <stdio.h>
void printit( int it)
{ printf( "It: %d\n", it);
}

odd.c:
#include <stdlib.h>
#include <stdio.h>
void new_printit( int it, char* who)
{ printf( "%s: It's %d\n", who, it);
}
#define WHO "main"
#define printit( i) new_printit( i, WHO)
#include "eg.h"
int main( int argc, char** argv)
{ printit( argc);
(printit)( argc);
return EXIT_SUCCESS;
}

eg.h:
void (printit)( int it);

The bits that I find puzzling are:
a. "(printit)" in eg.h. Without the brackets, of course, the
printit macro is invoked and syntax errors arise. b. "(printit)" in odd.c. This means that the printit() from
eg.c gets called, not the macro.

So it looks as if the preprocessor does not replace (printit)
with (<bodyofprintit>). Is this C? Is this only because the
printit macro takes parameters?

Yes, that is a feature of C. printit is #defined as a function-like macro. That means that anything intended to be an invocation of that macro must immediately be followed by a '('. If the identifier printit is used in any other context, it is not recognized as a macro.

Note that when you call a function by name, the function name decays into a pointer to a function, and expressions can be surrounded by parentheses without changing their value. As a result, the parentheses defeat the interpretation of printit as a macro name, while not interfering with recognition of it as a function name.
.