• Advertisement
Sign in to follow this  

Is this commenting macro safe to use?

This topic is 1340 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone.

 

I'm using a simple macro to comment out part of my code in release build, but i'm wondering if this could lead to some sort of problem, as i'm trying to cheat the precompiller into adding comments against the rule.

 

I use this to avoid writing duplicated code.

 

Basically, here is the macro

#if defined DEBUG
#define MACRO 
#else
#define MACRO );/ ## /
#endif

What it does is: If i'm in debug build, it does nothing. If i'm in release build, it close a function and comment the rest of the line.

The "/ ## /" part is needed to trick the compiler into thinking comment dont exist. But they do.

 

This is how i use the macro. (The code is simplified)

//Initialize a long list of interfaced classes into a map, allowing easy Factory access.
void Bar()
{
    //Assume each different letters is an interfaced class
    Foo(A0, A1 MACRO, A2, A3, A4);
    Foo(B0, B1 MACRO, B2, B3, B4);
    // Many Foo later...
    Foo(Z0, Z1 MACRO, Z2, Z3, Z4);
}

#if defined DEBUG
//Types don't really matter. Just the number of parameters is interesting.
void Foo(Type0, Type1, Type2, Type3, Type4)
{
    // Do something, in debug
}
#else
void Foo(Type0, Type1)
{
    // Do something, in release
}
#endif



As you can see, in release build, the compiler will see "Foo(A0, A1 );" as the comment will clear the rest of the line.
This way, i avoid writing this code:

#if defined DEBUG
Foo(A0, A1, A2, A3, A4);
Foo(B0, B1, B2, B3, B4);
// Many Foo later...
Foo(Z0, Z1, Z2, Z3, Z4);
#else
Foo(A0, A1);
Foo(B0, B1);
// Many Foo later...
Foo(Z0, Z1);
#endif

The reason i use it is to avoir writing duplicate code to avoid possible Copy/Paste errors.

As of writing this post, the macro work fine in either build, but i have this strange feeling i'm doing something cringe-worthy.

 

Am i really going overboard just to avoid writing duplicated code?

If so, is there other options?

Edited by Sunsharior

Share this post


Link to post
Share on other sites
Advertisement

I must have some gaps in my knowledge, as i thought comments are removed before the precompiler processes the macros?

I know a macro like this wont work, because the compiler will see the two slashes as a comment and remove/ignore them:

#define MACRO //

 

But why/how does the one in the OP work?

#define MACRO / ## /

Share this post


Link to post
Share on other sites

I do it this ugly way:

Foo(A0, A1 DEBUG(COMMA A2 COMMA A3 COMMA A4));
Foo(B0, B1 DEBUG(COMMA B2 COMMA B3 COMMA B4));

 
Variadic-arg comments work well here:
#define DEBUG_ARGS(...) , __VA_ARGS__

Foo(A0, A1, DEBUG_ARGS(A2, A3, A4));
 
This is GCC/MinGW, but it's standardized in C++11 now.
 

But why/how does the one in the OP work?
#define MACRO / ## /

 
## takes two characters and combine them. It takes / and / and turns it into //.


By the way, I agree that passing arguments only while debugging is sometimes suspect and should warrant a second glance at what you are doing. Edited by Servant of the Lord

Share this post


Link to post
Share on other sites


## takes two characters and combine them. It takes / and / and turns it into //.

Also known as token concatenation.

Share this post


Link to post
Share on other sites

 

But why/how does the one in the OP work?

#define MACRO / ## /

This uses the concatenation operator "##" to insert a comment "//"

Edit: beaten by servant of the lord.

Edited by Sunsharior

Share this post


Link to post
Share on other sites

Keep in mind that using token pasting to synthesize a comment is not actually allowed by the standard, as it explicitly states comment removal occurs before macro processing - many compilers do it after, or both before and after, but some (like gcc) will outright reject the macro as it would expand to an illegal token after the macro processing phase:

error: pasting "/" and "/" does not give a valid preprocessing token

I would be very wary of using that macro on an unknown compiler, there is no telling what it would actually do.

Share this post


Link to post
Share on other sites

As many already stated, i will revise the logic of my code to avoid using preprossesor-comments altogether. I already have an idea on how i might do that cleanly.

I understand now, the macro is not standard and should be avoided.

 

Thank you everyone.

Share this post


Link to post
Share on other sites

Yes, i do realize token pasting is occuring, the question was more in line with "why are comments allowed to exist after the macro processing", since afaik they are removed before it.

Bacterius' answer is what i was after, thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement