Max said:
Keith said:
pete said:
Max wrote:
This was asked in a C test. Is the following code legal C?
Is it legal in C90? C99?
Yes. Yes.
#define main()
int main
#define mainbody () { return 0; }
mainbody
It's as legal as
int main(){return 0;}
is.
[snips]
Compiling the code and/or examining the preprocessor output (assuming
your compiler supports this) won't definitively answer the question,
but it will give some good hints.
This question seems to be deeper than I thought. With '--traditional-cpp',
gcc's preprocessor produces
int main
#define mainbody () { return 0; }
mainbody
, that is, the '#define mainbody...' line is copied verbatim, without
printing any diagnostics, but only if main is a function-like macro.
Is there some older preprocessor standard that can explain that?
(Since somebody mentioned lcc-win, lcc (the original one, as well as
lcc-win and PellesC) do exactly the same.)
There was no actual *standard* prior to the introduction of ANSI C in
1989. But there were some behaviors that were fairly common in
pre-standard preprocessors, and that were changed in the standard.
The following is somewhat off-topic in that it's specific to gcc,
particularly to the GNU preprocessor. But it's also topical in that
it applies to the behavior of pre-ANSI compilers (to the extent that
"gcc -traditional-cpp" reproduces that behavior).
The issue in this particular case seems to be that the GNU
preprocessor in traditional mode doesn't like the reference to "main"
without parentheses after "main" has been defined as a function-like
macro. In standard C. this isn't a problem; the macro definition
simply doesn't apply unless "main" is followed by a '('.
Compiling the original program:
#define main()
int main
#define mainbody () { return 0; }
mainbody
with "gcc -Wtraditional" gives:
c.c:2:5: warning: function-like macro "main" must be used with
arguments in traditional C
Apparently the preprocessor, in traditional mode, stops working once
it encountters this error, and just passes its input to its output
with no changes. After changing the first line to "#define Main()",
"gcc -E -traditional-cpp" gives:
[# directives omitted]
int main
() { return 0; }
<OT>
"info cpp Traditional" should give you information on the
preprocessor's traditional mode, and how it differs from standard
mode.
</OT>
Note that the traditional mode is inexact, and doesn't necessarily
match any particular pre-standard implementation. It's not likely to
be useful unless you have a need to handle *really* old code.