[comp.lang.c] Macro expansions by 2 different C preprocessors

tej@uts.amdahl.com (Tejkumar Arora) (04/10/91)

I will use an example to illustrate the problem.

Consider a file x.h some of whose contents are as follows:
-------------------------------------
.....
int major();
....
#define major(x) _major(SOMECONST, x)
/* _major() returns a value of type int */
-------------------------------------

Now Consider this little program:
-------------------------------------
#include "x.h"
struct foo {
   .....
   sometype major;
   ....
};
main(){
....
... major(mumble)
}
-------------------------------------

I have compiled this program using two different compilers.

compiler A: fails to compile. gets stuck at the field major in struct foo.
	    thinks it is a macro and complains of missing argument.
compiler B: compiles successfully. determines from context & usage that the
	    field major is not a macro....
	    
Does someone know what the ANSI standards say about macro expansion?. I
tend to think that B is the way to go since it preprocesses intelligently,
and as far as I can see, B does not have to compromise any other functionality
to be able to do this. Some are of the opinion that this is just special casing
and is not a good feature. what do you think?
Thanks for your time,
-Tej
(tej@amdahl.com)

gwyn@smoke.brl.mil (Doug Gwyn) (04/10/91)

In article <acOn01ls55Ex00@amdahl.uts.amdahl.com> tej@amdahl.uts.amdahl.com (Tejkumar Arora) writes:
>compiler A: fails to compile. gets stuck at the field major in struct foo.
>	    thinks it is a macro and complains of missing argument.

That is the behavior of a Reiser CPP, one of many bugs it has.

>compiler B: compiles successfully. determines from context & usage that the
>	    field major is not a macro....

That is what a standard conforming compiler must do (the only relevant
context is whether or not the next preprocessing token after the identifier
is a left parenthesis).

steve@taumet.com (Stephen Clamage) (04/10/91)

tej@uts.amdahl.com (Tejkumar Arora) writes:

>int major();
>#define major(x) _major(SOMECONST, x)
>struct foo {
>   ... sometype major; ...
>};
>main(){
>... major(mumble)
>}

>compiler A: fails to compile. gets stuck at the field major in struct foo.
>	    thinks it is a macro and complains of missing argument.
>compiler B: compiles successfully. determines from context & usage that the
>	    field major is not a macro....
>Does someone know what the ANSI standards say about macro expansion?.

In section 3.8.3, the ANSI standard defines object-like macros as those
without parameters, and function-like macros as those with parameters.
(The precise definition is too wordy to reproduce here.)

A function-like macro name ('major' is one such) must be followed by
a left paren as the next token to be considered as a macro invocation.
Therefore, declaration and use of the structure field called 'major'
cannot be considered a macro invocation, and the use in main() must be
a macro invocation.

Compiler A does not follow the ANSI rules.  If it claims to be ANSI-
conforming, you should report this to the vendor.
-- 

Steve Clamage, TauMetric Corp, steve@taumet.com