By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,220 Members | 1,718 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,220 IT Pros & Developers. It's quick & easy.

Preprocessing directive in the middle of macro arguments

P: n/a
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){return a(
#if 0
#endif
0);}

More generally, this compiler seems confused by any preprocessing
directive in the middle of macro arguments, which comes handy e.g. to
conditionaly select one of several arguments passed to a macro.

Is it a compiler bug? Where does C89 define if this is valid or not?

TIA.
Francois Grieu
Jan 16 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
Francois Grieu <fg****@gmail.comwrites:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){return a(
#if 0
#endif
0);}

More generally, this compiler seems confused by any preprocessing
directive in the middle of macro arguments, which comes handy e.g. to
conditionaly select one of several arguments passed to a macro.

Is it a compiler bug? Where does C89 define if this is valid or not?
No, I think it is not permitted. In C89:

3.8.3 Macro replacement
...
If there are sequences of preprocessing tokens within the list of
arguments that would otherwise act as preprocessing directives, the
behavior is undefined.

The same wording appears in C99 but it is in section 6.10.3.

--
Ben.
Jan 16 '08 #2

P: n/a
On Jan 16, 8:57*am, Francois Grieu <fgr...@gmail.comwrote:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){return a(
#if 0
#endif
0);}

More generally, this compiler seems confused by any preprocessing
directive in the middle of macro arguments, which comes handy e.g. to
conditionaly select one of several arguments passed to a macro.

Is it a compiler bug? Where does C89 define if this is valid or not?

TIA.
* Francois Grieu
It's not a bug; you cannot embed preprocessor commands in a macro.
All preprocessor directives are processed before any macro expansion
takes place, so any preprocessor directives embedded in a macro will
not be recognized as such, but will instead be translated as regular C
code.
Jan 16 '08 #3

P: n/a
John Bode wrote:
On Jan 16, 8:57 am, Francois Grieu <fgr...@gmail.comwrote:
>One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){return a(
#if 0
#endif
0);}

More generally, this compiler seems confused by any preprocessing
directive in the middle of macro arguments, which comes handy e.g. to
conditionaly select one of several arguments passed to a macro.

Is it a compiler bug? Where does C89 define if this is valid or not?

TIA.
Francois Grieu

It's not a bug; you cannot embed preprocessor commands in a macro.
All preprocessor directives are processed before any macro expansion
takes place, so any preprocessor directives embedded in a macro will
not be recognized as such, but will instead be translated as regular C
code.
The OP's code has no embedded directives; it's equivalent to
#define a(b) b
int main(void){return a(
0);}
Which is good C, IMHO. So I think it's a compiler bug.
<OT>
Getting the C front end right is surprisingly hard; there are enough C
vendors to make a market for C front end parsers, and it exists.
Still, some people do it on their own, and sometimes incorrectly. I had
trouble with Keil for ARM (see
http://www.macroexpressions.com/dl/compileme.c), but I never tried their
latest version.
I wonder if this fixes the OP problem :)
#de\
fine \
a(b\
b)=bb
</OT>
--
Ark
Jan 17 '08 #4

P: n/a
Ark Khasin <ak*****@macroexpressions.comwrites:
John Bode wrote:
>On Jan 16, 8:57 am, Francois Grieu <fgr...@gmail.comwrote:
>>One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){return a(
#if 0
#endif
0);}

More generally, this compiler seems confused by any preprocessing
directive in the middle of macro arguments, which comes handy e.g. to
conditionaly select one of several arguments passed to a macro.

Is it a compiler bug? Where does C89 define if this is valid or not?

It's not a bug; you cannot embed preprocessor commands in a macro.
All preprocessor directives are processed before any macro expansion
takes place, so any preprocessor directives embedded in a macro will
not be recognized as such, but will instead be translated as regular C
code.
The OP's code has no embedded directives; it's equivalent to
#define a(b) b
int main(void){return a(
0);}
Which is good C, IMHO. So I think it's a compiler bug.
I disagree. Are you saying that the OP's code is equivalent to the
above because of John Bode's: "All preprocessor directives are
processed before any macro expansion takes place"? If so, I think you
have been misled. In section 5.1.1.2 ("Translation phases") is says:

4. Preprocessing directives are executed, macro invocations are
expanded, and _Pragma unary operator expressions are executed. If a
character sequence that matches the syntax of a universal character
name is produced by token concatenation (6.10.3.3), the behavior is
undefined. A #include preprocessing directive causes the named
header or source file to be processed from phase 1 through phase 4,
recursively. All preprocessing directives are then deleted.

so all pre-processing happens "at once". I may have missed something
that does give the OP's code a portable meaning, but I need
persuading. Until then I stand by my previous quote that:

If there are sequences of preprocessing tokens within the list of
arguments that would otherwise act as preprocessing directives,
the behavior is undefined. [6.10.3]

--
Ben.
Jan 17 '08 #5

P: n/a
Ben Bacarisse wrote:
Ark Khasin <ak*****@macroexpressions.comwrites:
>John Bode wrote:
>>On Jan 16, 8:57 am, Francois Grieu <fgr...@gmail.comwrote:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){return a(
#if 0
#endif
0);}

More generally, this compiler seems confused by any preprocessing
directive in the middle of macro arguments, which comes handy e.g. to
conditionaly select one of several arguments passed to a macro.

Is it a compiler bug? Where does C89 define if this is valid or not?
It's not a bug; you cannot embed preprocessor commands in a macro.
All preprocessor directives are processed before any macro expansion
takes place, so any preprocessor directives embedded in a macro will
not be recognized as such, but will instead be translated as regular C
code.
The OP's code has no embedded directives; it's equivalent to
#define a(b) b
int main(void){return a(
0);}
Which is good C, IMHO. So I think it's a compiler bug.

I disagree. Are you saying that the OP's code is equivalent to the
above because of John Bode's: "All preprocessor directives are
processed before any macro expansion takes place"? If so, I think you
have been misled. In section 5.1.1.2 ("Translation phases") is says:

4. Preprocessing directives are executed, macro invocations are
expanded, and _Pragma unary operator expressions are executed. If a
character sequence that matches the syntax of a universal character
name is produced by token concatenation (6.10.3.3), the behavior is
undefined. A #include preprocessing directive causes the named
header or source file to be processed from phase 1 through phase 4,
recursively. All preprocessing directives are then deleted.

so all pre-processing happens "at once". I may have missed something
that does give the OP's code a portable meaning, but I need
persuading. Until then I stand by my previous quote that:

If there are sequences of preprocessing tokens within the list of
arguments that would otherwise act as preprocessing directives,
the behavior is undefined. [6.10.3]
I read the OP's code as follows:
1. definition of a(b) is read
2. macro invocation "a(" is found; need to build replacement list
3. the #if directive is found; need to evaluate
4. expression evaluates to 0, need to skip to #endif
5. skipped to #endif; continue building replacement list
6. found a replacement parameter and a right paren; r.l. built.
7. perform the macro expansion
8. etc.

I see /your/ reading of the code. If it were correct, we'd have an
ambiguity. However, 6.10.3 resolves it:
8 If a # preprocessing token, followed by an identifier, occurs
lexically at the point at which a preprocessing directive could begin,
the identifier is not subject to macro replacement.
That is, #if is not replaced which turns it into a directive - which
goes on to skip to #endif

--
Ark
Jan 18 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.