473,232 Members | 1,556 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,232 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 6239
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...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
0
Git
by: egorbl4 | last post by:
Скачал я git, хотел начать настройку, а там вылезло вот это Что это? Что мне с этим делать? ...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...
0
by: MeoLessi9 | last post by:
I have VirtualBox installed on Windows 11 and now I would like to install Kali on a virtual machine. However, on the official website, I see two options: "Installer images" and "Virtual machines"....
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...

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.