Oliver Friedrich
Oliver Friedrich

Reputation: 9240

dangling if and macro

I'm in the need to get rid of warnings, one of it is a -Wdangling-else. It notes a dangling if inside the following macro definition:

#define FOR_EACH_REF(var, container) \
    if(bool _cont = true) \
      for(our::remove_reference<decltype(container)>::type::iterator _it = (container).begin(); _it != (container).end() && _cont; ++_it) \
        if((_cont = false)) {} else \
          for(our::remove_reference<decltype(container)>::type::value_type& var = *_it; !_cont; _cont = true)

I must admit, I do not really get into this macro and thus do not know, how to resolve this warning.

Could anyone help me with an explanation on how to avoid the dangling else?

Upvotes: 2

Views: 255

Answers (2)

Jarod42
Jarod42

Reputation: 217408

You might reverse the condition to avoid to have empty if-block and so problematic else:

#define FOR_EACH_REF(var, container) \
    if (bool _cont = true) \
      for(our::remove_reference<decltype(container)>::type::iterator _it = (container).begin(); _it != (container).end() && _cont; ++_it) \
        if(!(_cont = false)) \
          for(our::remove_reference<decltype(container)>::type::value_type& var = *_it; !_cont; _cont = true)

Since C++11, it would even be easy to write:

#define FOR_EACH_REF(var, container) for (auto& var : container)

Upvotes: 3

Vittorio Romeo
Vittorio Romeo

Reputation: 93294

how to avoid the dangling else?

The easiest (and not recommended) option is disabling the warning in the compiler with -Wno-dangling-else.

The real solution is to add braces around the if/else branches:

#define FOR_EACH_REF(var, container) \
    if(bool _cont = true) { \
    for(/* ... */) \
        if((_cont = false)) {} else { \
        for(/* ... */)

#define FOR_EACH_REF_END }}

Usage:

FOR_EACH_REF(foo, bar) 
{ 

}
FOR_EACH_REF_END

If you want to iterate over a range, C++11 provides language syntax for that, which should be used instead of this abominable macro:

for(const auto& var : container) { }

Upvotes: 2

Related Questions