Edward Rutherford
6/11/2011 8:01:00 PM
Keith Thompson wrote:
> Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> writes:
>> Keith Thompson wrote:
>>> Edward Rutherford <edward.p.rutherford79@REMOVETHIS.gmail.com> 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.
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.
/EPR