2

In a C/C++ code project, I would like to find all if/else sentences which are not using curly braces. Is there any compiler check or utility to find them?

The main problem is that I want to redefine some debug macros to avoid traces evaluation in some conditions (does any know any other solution?). And I need to find them to avoid the “dangling-else problem”, as pointed out in "if" block without curly braces makes subsequent "else if" nested

Code pieces:

Before modification:

DEBUG GET_DEBUG_DST(DEBUG_LEVEL_DEBUG).nospace() << DEBUG_PREFIX << __PRETTY_FUNCTION__

Now we would use an if without braces inside:

DEBUG if (getDebugmode(DEBUG_LEVEL_DEBUG)) GET_DEBUG_DST(DEBUG_LEVEL_DEBUG).nospace() << DEBUG_PREFIX << __PRETTY_FUNCTION__

Example of problematic code:

if (my condition)
    DEBUG << "hi there";
else
    {some more code;}
Community
  • 1
  • 1
kikeenrique
  • 2,589
  • 2
  • 25
  • 46
  • 2
    In first place, it would be a better idea to replace this kind of debugging log with something reasonable and sane. –  Apr 05 '13 at 10:27
  • try to create a compilation error – Alon Apr 05 '13 at 10:29
  • @H2CO3 I know, but I didn't start it and I've to deal with it. – kikeenrique Apr 05 '13 at 10:29
  • @Alon I've tried to think a way to raise a compilation error, but haven't found any yet. Any idea? – kikeenrique Apr 05 '13 at 10:31
  • You could use a regular expression of the form `if\s*\(.*\)\s*^{` or similar but as others have commented you should fix the debugging code rather than the rest of the code – msam Apr 05 '13 at 10:34

3 Answers3

4

Just invert the logic, and put the active part in the else branch:

#define DEBUG if( !getDebugmode( DEBUG_LEVEL_DEBUG ) )              \
        ;                                                           \
    else                                                            \
        GET_DEBUG_DST( DEBUG_LEVEL_DEBUG ).nospace()                \
            << DEBUG_PREFIX << __PRETTY_FUNCTION__

Since there is a matching else for the if, it can't pick up any additional else.

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • Good solution but since OP seems to assume that the `if` needs to be inside the `#define` it’s worth noting that this isn’t the case at all, and there are other solutions – one would be to have a proxy stream object in which the overloaded `operator<<` takes over the check for the debugging mode, and the macro would simply be `#define DEBUG get_stream_proxy() << DEBUG_PREFIX << __PRETTY_FUNCTION__` … – Konrad Rudolph Apr 05 '13 at 10:51
  • @KonradRudolph I thought that one, but I discarded it as it would not avoid evaluating all code after the operator<<, would it? – kikeenrique Apr 05 '13 at 10:54
  • @kikeenrique I usually use the proxy solution myself. Done correctly, the _expressions_ after the `<<` will be evaluated, but there will be no conversions unless tracing is active. Typically, the expressions are fairly trivial, and the real cost is the conversion, but one never knows. – James Kanze Apr 05 '13 at 11:48
1

I would like to find in a c/c++ code project all if/else sentences which are not using curly braces. Is there any compiler check or utility to find them?

This sounds like the x-y problem. If you are trying to replace the DEBUG macro with a no-op that will not invalidate the syntax of the if, you can use:

#ifdef DEBUG_ENABLED
#define DEBUG GET_DEBUG_DST(DEBUG_LEVEL_DEBUG).nospace() << DEBUG_PREFIX // ...
#else
#define DEBUG do {;} while(false); /##/
#endif

In this case, the DEBUG will be a valid operation (doesn't invalidate the else due to nothing in the if block), and anything that's on the same line (the debug message data) will evaluate to:

if (my condition)
    do {;} while(false); // << "hi there";
else
    {some more code;}

This has the disadvantage of not allowing for multiline debug comments though:

if (my condition)
    DEBUG << "hi there"
        << "some more data on a different line"; // causes error if DEBUG is no-op
else
    {some more code;}
utnapistim
  • 26,809
  • 3
  • 46
  • 82
  • This fixes the problem in compilation time, which is solved in a similar way, but the purpose is to modify traces on runtime, thats why I need to use the if(). – kikeenrique Apr 05 '13 at 10:42
  • 1
    Unfortunately, like many preprocessing hacks, that won't work. Comments are removed *before* macro expansion, which works on preprocessor tokens rather than source characters. So after processing, you'll end up with two `/` tokens giving a syntax error. – Mike Seymour Apr 05 '13 at 10:45
-1

Bad idea.

Use:

#define debug(x) do { if (DEBUG_LEVEL) print_stuff(x); } while(0)

which avoids the issue.

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
  • The problem is the use of the macro, which currently is DEBUG << "something"; It would be easier that way, but changing the macro use is not possible. – kikeenrique Apr 05 '13 at 10:32
  • You'll have to find all the broken code then. Not sure there is an easy way to do that... – Mats Petersson Apr 05 '13 at 10:36