473,394 Members | 1,759 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

Preprocessing directive in the middle of macro arguments

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
5 6257
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
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
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
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
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Ron | last post by:
Please, consider the following code: const int a = 1; #if a == 1 #define VAR 200 #else #define VAR 100 #endif int main() {
1
by: Alex Sedow | last post by:
Where to get/buy tool for partial preprocessing? 1. What I mean by partial macro preprocessing. This is mode in which almost sources (>99%) is not preprocessed. But some macros (setted by...
10
by: Karim Thapa | last post by:
Why following macro does not work? #define removebrace(x) x void Foo(int a, int b, char *txt, int d, int e); main() {
12
by: Francois Grieu | last post by:
Can #include safely use a preprocessing token, as in #define HEADERFILE "stdio.h" #include HEADERFILE int main(void) {return printf("Hello, world\n")*0;} TIA, François Grieu
5
by: cody | last post by:
the following leads to an error (note that TEST is not defined): #if TEST string s = @" #"; // <-- the error is "preprocessing directive expected" #endif also, here we get the same error: ...
4
by: Henrik Goldman | last post by:
I have an application which compiles on a number of different platforms. Now I'm trying to incorporate an external library which is only available to a subset of the platforms that my application...
9
by: Francois Grieu | last post by:
Consider this macro // check if x, assumed of type unsigned char, is in range #define ISVALID(x) ((x)>=0x20 && (x)<=0x7E) Of course, this can't be safely used as in if (ISVALID(*p++)) foo();...
4
by: ludovicd | last post by:
Hi, I look for a way a put the argument of a fonction between single quotes within a preprocessor directive such as: #define fct(v) 'v' (or something equivalent) fct(\n);
6
by: Bing | last post by:
Hi folks, Is there a way to define a macro that may contain #include directive in its body. If I just put the "#include", it gives error C2162: "expected macro formal parameter" since here I am...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.