Infinite loop in constructor without for or while
I did a test here, but the output is a loop without ending, I don't know why.
Actually, I am doing another test, but when I wrote this, I don't understand how the loop occurred. It is output "ABC" repeatedly.
#include <map>
#include <string>
#include <iostream>
class test
{
public:
std::map <int, int> _b;
test();
test (std::map<int, int> & im);
~test();
};
test::test()
{
std::cout<<"abc";
_b.clear();
_b[1]=1;
test(_b);
}
test::test(std::map <int, int>& im)
{
std::cout<<im[1];
}
test::~test() {};
int main ()
{
test a;
}
The issue here is that the compiler interprets
test(_b);
Not as code that creates a temporary object of type test
passing in parameter _b
, but as a variable declaration for a variable named _b
of type test
, using the default constructor. Consequently, what looks like a piece of code that creates a temporary test
object using the second constructor is instead recursively creating a new object of type test
and invoking the constructor another time.
To fix this, you can give the variable an explicit name, such as
test t(_b);
This can only be interpreted as a variable of type test
named t
, initialized using the second constructor.
I have never seen this before, and I've been programming in C++ for years. Thanks for showing me yet another corner case of the language!
For an official explanation: According to the C++03 ISO spec, §6.8:
There is an ambiguity in the grammar involving expression-statements and declarations: An expression-statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration.
(My emphasis). In other words, any time C++ could interpret a statement as either an expression (the temporary object cast) or as a declaration (of a variable), it will pick the declaration. The C++ spec explicitly gives
T(a);
As an example of a declaration, not a cast of a
to something of type T
.
This is C++'s Most Vexing Parse - what looks like an expression is instead getting interpreted as a declaration. I've seen the MVP before, but I have never seen it in this context.
Hope this helps!