simplecpp icon indicating copy to clipboard operation
simplecpp copied to clipboard

C89 6.8.3.5 example #3, failure

Open ghost opened this issue 4 years ago • 1 comments

Is it your intention to be standards-compliant? Not trying to be nit-picky here, but the standards define the preprocessor's behavior to a certain level of precision, and the rules for expansions in particular are tricky; they provide non-trivial examples which be used to ensure you get it right. simplecpp seems to have some problems in this area. I've documented one in detail here, but I've noticed others, and I'm happy to share those if anyone is interested.

Example 3 is the first non-trivial example, and it's flat out rejected with EXAMPLE3:10: syntax error: failed to expand 'm', Wrong number of parameters for macro 'f'.

Here's the full example:

/* complete example #3 from ANSI C89 standard, 6.8.3.5 */
/* (The equivalent [expanded] example in C99 is found in 6.10.3.5.) */

#define x       3
#define f(a)    f(x * (a))
#undef  x
#define x       2
#define g       f
#define z       z[0]
#define h       g(~
#define m(a)    a(w)
#define w       0,1
#define t(a)    a

f(y+1) + f(f(z)) % t(t(g)(0) + t)(1);

g(x+(3,4)-w) | h 5) & m
    (f)^m(m);

Now, we can reproduce the problem with this reduced fragment:

#define f(a)    a
#define m(a)    a(w)
#define w       0,1

m(f)

which should produce

0,1

as its expansion, but results in the same error. It seems that w is being expanded prematurely. The transformation should be

m(f) -> f(w) -> 0,1

but (I'm surmising) is instead being expanded

m(f) -> f(0,1) -> ERROR

which is incorrect.

The relevant text is in C89 6.8.3.1 (C99 6.10.3.1)

After the arguments for the invocation of a function-like macro have been identified,
argument substitution takes place. A parameter in the replacement list, unless preceded
by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is
replaced by the corresponding argument after all macros contained therein have been
expanded. Before being substituted, each argument’s preprocessing tokens are
completely macro replaced as if they formed the rest of the preprocessing file; no other
preprocessing tokens are available.

Note in particular that expansions during replacement are limited to macro arguments. No other expansions are performed. The w should not be expanded as part of the expansion of m (since it's not an argument to m) but rather as an argument to f.

Hope this helps...

ghost avatar Jul 15 '21 15:07 ghost

yes it is the intention to try to be standards compliant.

thanks for this report.

danmar avatar Jul 16 '21 17:07 danmar