Reputation: 6084
If I compile the following small programm with Visual Studio 2015, I get the following compiler warning in line 9:
warning C4456: Declaration of "iter" shadows previous declaration
This is my small program:
#include <iostream>
#include <boost/variant.hpp>
int main(int argc, char** args) {
boost::variant<double, int> v{ 3.2 };
if (auto iter = boost::get<int>(&v)) {
std::cout << *iter << std::endl;
}
else if( auto iter = boost::get<double>(&v)) {
std::cout << *iter << std::endl;
}
}
I'm curious if this is a compiler bug or a serious error.
Revised
As @Zeta found out, the following is legal C++ code, even I never imagined. The program will crash, due to using an undefined iter
.
#include <iostream>
#include <boost/variant.hpp>
int main(int, char**) {
boost::variant<double, int> v{ 3.2 };
if (auto iter = boost::get<int>(&v)) {
std::cout << *iter << std::endl;
}
else if( auto iter2 = boost::get<double>(&v)) {
std::cout << *iter2 << std::endl;
std::cout << *iter << std::endl;
}
return 0;
}
Upvotes: 0
Views: 1129
Reputation: 105935
VS is correct. You have two iter
at hand:
#include <iostream>
#include <boost/variant.hpp>
int main(int argc, char** args) {
boost::variant<double, int> v{ 3.2 };
if (auto iter = boost::get<int>(&v)) {
std::cout << *iter << std::endl;
}
else if( auto iter2 = boost::get<double>(&v)) {
std::cout << *iter << std::endl; // whoops
}
}
That's because
if(value = foo()) {
bar();
} else {
quux();
}
is the same as
{
value = foo();
if(value) {
bar();
} else {
quux();
}
}
Note that value
is in scope for else
. This includes any nested if
within the (implicit) else
block. You can look this up in C++11's [stmt.select] section, paragraph 3:
… A name introduced by a declaration in a condition (either introduced by the type-specifier-seq or the declarator of the condition) is in scope from its point of declaration until the end of the substatements controlled by the condition. If the name is re-declared in the outermost block of a substatement controlled by the condition, the declaration that re-declares the name is ill-formed. [ Example:
if (int x = f()) { int x; // ill-formed, redeclaration of x } else { int x; // ill-formed, redeclaration of x }
Upvotes: 2