Reputation: 9240
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
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
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