Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Another macro question

Reply
Thread Tools

Another macro question

 
 
Edward Rutherford
Guest
Posts: n/a
 
      06-09-2011
I am porting a codebase that makes extensive use of the following
construction:

#define CAT(a,b) a##b
#define COMMENT CAT(/,/)
COMMENT This is a comment

It works as intended on the original Windows system, but not on the
target compiler, which claims that comments should not be processed after
macro expansion. So I have an odd situation where the preprocessor output
is as intended and is compilable, whereas the original file is not.

What is the truth, according to the standards? If it is invalid, can
anyone suggest an alternative definition for the COMMENT macro that will
achieve the same effect?

Thanks.
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      06-09-2011
Edward Rutherford <(E-Mail Removed)> writes:
> I am porting a codebase that makes extensive use of the following
> construction:
>
> #define CAT(a,b) a##b
> #define COMMENT CAT(/,/)
> COMMENT This is a comment
>
> It works as intended on the original Windows system, but not on the
> target compiler, which claims that comments should not be processed after
> macro expansion. So I have an odd situation where the preprocessor output
> is as intended and is compilable, whereas the original file is not.
>
> What is the truth, according to the standards? If it is invalid, can
> anyone suggest an alternative definition for the COMMENT macro that will
> achieve the same effect?


The target compiler is correct. Comments are replaced by space
characters in translation phase 3; macros invocations are expanded
in phase 4 (C99 5.1.1.2). By the time the "//" is produced, it
shouldn't be recognized as a comment delimiter.

I don't believe there's any way for a macro to expand to a comment
delimiter.

Why not just use "//"?

Or, if you must use "COMMENT" for some reason, modify your build
procedure so each source file is filtered through something that
replaces "COMMENT" by "//" (watch out for occurrences of "COMMENT"
in string literals, header names, and, in principle, character
constants).

--
Keith Thompson (The_Other_Keith) http://www.velocityreviews.com/forums/(E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
 
 
 
Edward Rutherford
Guest
Posts: n/a
 
      06-10-2011
Keith Thompson wrote:

> Edward Rutherford <(E-Mail Removed)> writes:
>> I am porting a codebase that makes extensive use of the following
>> construction:
>>
>> #define CAT(a,b) a##b
>> #define COMMENT CAT(/,/)
>> COMMENT This is a comment
>>
>> It works as intended on the original Windows system, but not on the
>> target compiler, which claims that comments should not be processed
>> after macro expansion. So I have an odd situation where the
>> preprocessor output is as intended and is compilable, whereas the
>> original file is not.
>>
>> What is the truth, according to the standards? If it is invalid, can
>> anyone suggest an alternative definition for the COMMENT macro that
>> will achieve the same effect?

>
> The target compiler is correct. Comments are replaced by space
> characters in translation phase 3; macros invocations are expanded in
> phase 4 (C99 5.1.1.2). By the time the "//" is produced, it shouldn't
> be recognized as a comment delimiter.
>
> I don't believe there's any way for a macro to expand to a comment
> delimiter.
>
> Why not just use "//"?
>
> Or, if you must use "COMMENT" for some reason, modify your build
> procedure so each source file is filtered through something that
> replaces "COMMENT" by "//" (watch out for occurrences of "COMMENT" in
> string literals, header names, and, in principle, character constants).


Keith.

Rereading my original post I see that it may have been misleading as to
how this macro is used.

The idea is that it provides a way to selectively comment out individual
lines of code: in effect, it is to single lines what
#if DEBUGMODE...#endif is to blocks.

So an example of a COMMENT line might be
COMMENT logger_write(LOG_DEBUG2, "Entering foo function, x=%d", x);

The COMMENT macro can either be defined as in my original post (to
exclude the line), or as a null macro (to include the line).

One possibility would be to look for all occurrences of COMMENT lines and
surround them by #if...#endif blocks. However, this would clutter the
code and make it much harder to read.

Is there a portable, standards-compliant way to define COMMENT to achieve
the desired effect?

/EPR
 
Reply With Quote
 
Keith Thompson
Guest
Posts: n/a
 
      06-10-2011
Edward Rutherford <(E-Mail Removed)> writes:
> Keith Thompson wrote:
>> Edward Rutherford <(E-Mail Removed)> writes:
>>> I am porting a codebase that makes extensive use of the following
>>> construction:
>>>
>>> #define CAT(a,b) a##b
>>> #define COMMENT CAT(/,/)
>>> COMMENT This is a comment
>>>
>>> It works as intended on the original Windows system, but not on the
>>> target compiler, which claims that comments should not be processed
>>> after macro expansion. So I have an odd situation where the
>>> preprocessor output is as intended and is compilable, whereas the
>>> original file is not.
>>>
>>> What is the truth, according to the standards? If it is invalid, can
>>> anyone suggest an alternative definition for the COMMENT macro that
>>> will achieve the same effect?

>>
>> The target compiler is correct. Comments are replaced by space
>> characters in translation phase 3; macros invocations are expanded in
>> phase 4 (C99 5.1.1.2). By the time the "//" is produced, it shouldn't
>> be recognized as a comment delimiter.
>>
>> I don't believe there's any way for a macro to expand to a comment
>> delimiter.
>>
>> Why not just use "//"?
>>
>> Or, if you must use "COMMENT" for some reason, modify your build
>> procedure so each source file is filtered through something that
>> replaces "COMMENT" by "//" (watch out for occurrences of "COMMENT" in
>> string literals, header names, and, in principle, character constants).

>
> Rereading my original post I see that it may have been misleading as to
> how this macro is used.
>
> The idea is that it provides a way to selectively comment out individual
> lines of code: in effect, it is to single lines what
> #if DEBUGMODE...#endif is to blocks.
>
> So an example of a COMMENT line might be
> COMMENT logger_write(LOG_DEBUG2, "Entering foo function, x=%d", x);
>
> The COMMENT macro can either be defined as in my original post (to
> exclude the line), or as a null macro (to include the line).
>
> One possibility would be to look for all occurrences of COMMENT lines and
> surround them by #if...#endif blocks. However, this would clutter the
> code and make it much harder to read.
>
> Is there a portable, standards-compliant way to define COMMENT to achieve
> the desired effect?


So you want something like

#if DEBUGMODE
#define COMMENT //
#else
#define COMMENT
#endif

(except that it actually works), right?

I don't think you can *quite* do that. What you can do is:

#if DEBUGMODE
#define COMMENT(arg) arg
#else
#define COMMENT(arg)
#endif

Then your COMMENT line would have to look like:

COMMENT(logger_write(LOG_DEBUG2, "Entering foo function, x=%d", x)

The semicolon inside the parentheses looks a bit funny, but the idea is
that the argument to COMMENT is an arbitrary line of code, not an
expression. You can probably get away with:

COMMENT(logger_write(LOG_DEBUG2, "Entering foo function, x=%d", x));

but that gives you an extra bare semicolon, which is ok in some contexts
but not in others.

Or you can make logger_write (and anything similar) a macro whose
definition depends on DEBUGMODE (and consider calling it LOGGER_WRITE).
Note that variadic macros are a new feature in C99; you might need to
use something like:

LOGGER_WRITE((LOG_DEBUG2, "Entering foo function, x=%d", x));

so it takes exactly one argument.

--
Keith Thompson (The_Other_Keith) (E-Mail Removed) <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
 
Reply With Quote
 
Shao Miller
Guest
Posts: n/a
 
      06-11-2011
On 6/11/2011 3:01 PM, Edward Rutherford wrote:
> Keith Thompson wrote:
>> ...
>> So you want something like
>>
>> #if DEBUGMODE
>> #define COMMENT //
>> #else
>> #define COMMENT
>> #endif
>>
>> (except that it actually works), right?
>>
>> I don't think you can *quite* do that. What you can do is:
>>
>> #if DEBUGMODE
>> #define COMMENT(arg) arg
>> #else
>> #define COMMENT(arg)
>> #endif
>> ...

>
> Exactly right, Keith, except that your
> #define COMMENT //
> could never work because the // would be interpreted as a comment on the
> macro line and get deleted, i.e. the line would be equivalent to
> #define COMMENT
>
> I assume this is the reason for the futzing around with stringifying
> two / characters in the macro from my original post.
>
> Your suggested functionlike macro may be the best available, but it's a
> shame there's not a more elegant solution.


"So you want something like...except that it actually works...I don't
think you can..."
"except that your...could never work because..."

It's nice to see agreement.
 
Reply With Quote
 
Jens
Guest
Posts: n/a
 
      06-12-2011
On 9 Jun., 20:32, Edward Rutherford
<(E-Mail Removed)> wrote:
> I am porting a codebase that makes extensive use of the following
> construction:
>
> #define CAT(a,b) a##b
> #define COMMENT CAT(/,/)
> COMMENT This is a comment
>
> It works as intended on the original Windows system, ...


As others have already mentioned this can't work with a complying
compiler.

But it is also not so productive, I think. This hides your code until
the day you have to debug something so there are big chances that your
code that you commented out didn't evolve in parallel with your other
code. So generally it wouldn't compile anymore.

A better solution is to put the debug code in something like

#ifndef DEBUG_ME
# define DEBUG_ME 0
#endif

if (DEBUG_ME) {
// your code comes here
}

There, the debug code is checked at every compile but any decent
compiler nowadays should completely ignore it afterwards. Then, the
day you want to use this code you can compile with -DDEBUG_ME=1 and
the code is executed.
 
Reply With Quote
 
luser- -droog
Guest
Posts: n/a
 
      06-12-2011
On Jun 9, 1:32*pm, Edward Rutherford
<(E-Mail Removed)> wrote:
> I am porting a codebase that makes extensive use of the following
> construction:
>
> #define CAT(a,b) a##b
> #define COMMENT CAT(/,/)
> COMMENT This is a comment
>
> It works as intended on the original Windows system, but not on the
> target compiler, which claims that comments should not be processed after
> macro expansion. So I have an odd situation where the preprocessor output
> is as intended and is compilable, whereas the original file is not.
>
> What is the truth, according to the standards? If it is invalid, can
> anyone suggest an alternative definition for the COMMENT macro that will
> achieve the same effect?
>
> Thanks.


What about doing an extra pre-process step?
% cc -E source_with_COMMENT.c > source_without_COMMENT.c
% cc source_without_COMMENT.c

 
Reply With Quote
 
luser- -droog
Guest
Posts: n/a
 
      06-12-2011
On Jun 12, 2:34*am, Jens <(E-Mail Removed)> wrote:
> A better solution is to put the debug code in something like
>
> #ifndef DEBUG_ME
> # define DEBUG_ME 0
> #endif
>
> if (DEBUG_ME) {
> *// your code comes here
>
> }
>
> There, the debug code is checked at every compile but any decent
> compiler nowadays should completely ignore it afterwards. Then, the
> day you want to use this code you can compile with -DDEBUG_ME=1 and
> the code is executed.


It's also straightforward to change from a compile-time option to a
run-time option by changing DEBUG_ME to a variable. You lose the
optimize-away-when-not-in-use feature, but it greatly increases your
flexibility. Maybe you don't need the debugging output during
initialization, but you need a trace from the main loop....
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dedicated Macro or Normal Macro? John Ortt Digital Photography 5 11-22-2005 12:43 PM
Macro lens on a camera with a macro setting??? mitchell.chris@gmail.com Digital Photography 2 09-28-2005 07:55 AM
in S.E. Asia : Canon EOS 300d with 100 macro ED vs. Nikon D70 with Nikon 105 macro ? J. Cod Digital Photography 0 09-29-2004 05:46 AM
#define macro to enclose an older macro with strings Dead RAM C++ 20 07-14-2004 10:58 AM
macro name from macro? D Senthil Kumar C Programming 1 09-21-2003 07:02 PM



Advertisments