473,763 Members | 1,893 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

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){retu rn 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 6298
Francois Grieu <fg****@gmail.c omwrites:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){retu rn 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.c omwrote:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){retu rn 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.c omwrote:
>One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){retu rn 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){retu rn 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*****@macroe xpressions.comw rites:
John Bode wrote:
>On Jan 16, 8:57 am, Francois Grieu <fgr...@gmail.c omwrote:
>>One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){retu rn 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
conditional y 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){retu rn 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 ("Translatio n 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*****@macroe xpressions.comw rites:
>John Bode wrote:
>>On Jan 16, 8:57 am, Francois Grieu <fgr...@gmail.c omwrote:
One of the C compiler that I use <OT>(Keil's CX51)</OTbarks at

#define a(b) b
int main(void){retu rn 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
conditiona ly 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){retu rn 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 ("Translatio n 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
2145
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
2882
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 options) will be "executed". This feature maybe used for: a) exclude some (nonpublic, temple or test) parts of source code. b) simplify source code (remove unused macros, replace some macros to better undestanding). Example (PRIVATE macro executed,...
10
2433
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
1983
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
5511
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: #if TEST
4
1592
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 support. This is ok as it will give increased usability on some platforms but not all. The problem however is to remove code at compiletime when my application is compiled on a platform which does not support this library. Using the...
9
321
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(); where p is a pointer ot unsigned char.
4
1456
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
6975
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 not using # to concatenate strings. If I use "\# include", then I receive the following two errors: error C2017: illegal escape sequence error C2121: '#' : invalid character : possibly the result of a macro
0
9566
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9389
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9828
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8825
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7370
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6643
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5271
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5410
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
3
2797
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.