Bo Persson
10/19/2008 11:35:00 AM
Erik Wikström wrote:
> On 2008-10-19 12:18, Vijay Meena wrote:
>> On Oct 19, 2:05 pm, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
>>> Erik Wikström wrote:
>>>> On 2008-10-19 06:39, Sam wrote:
>>>>> Kai-Uwe Bux writes:
>>>
>>>>>> Vijay Meena wrote:
>>>
>>>>>>> Hi,
>>>>>>> This code is of no use. But I am just curious to know about
>>>>>>> what happening here.
>>>
>>>>>>> #include <iostream>
>>>>>>> using namespace std;
>>>
>>>>>>> class Foo {
>>>>>>> private:
>>>>>>> int i;
>>>>>>> public:
>>>>>>> Foo() {
>>>>>>> cout << "Foo::Foo()" << endl;
>>>>>>> Foo(i);
>>>>>>> }
>>>>>>> Foo(int i) : i(i) {
>>>>>>> cout << "Foo::Foo(int)" << endl;
>>>>>>> }
>>>>>>> ~Foo() {
>>>>>>> cout << "Foo::~Foo()" << endl;
>>>>>>> }
>>>>>>> };
>>>
>>>>>>> int main(int argc, char *argv[])
>>>>>>> {
>>>>>>> Foo();
>>>>>>> }
>>>
>>>>>>> I am getting infinite call to "Foo::Foo()". Program is not
>>>>>>> even executing "Foo::Foo(int)".
>>>
>>>>>> Hm, I am flabbergasted. The following _does_ the expected:
>>>
>>>>>> Foo() {
>>>>>> cout << "Foo::Foo()" << endl;
>>>>>> Foo( this->i );
>>>>>> }
>>>
>>>>>> and prints:
>>>
>>>>>> Foo::Foo()
>>>>>> Foo::Foo(int)
>>>>>> Foo::~Foo()
>>>>>> Foo::~Foo()
>>>
>>>>>> I have no idea, what difference the "this->" should make.
>>>
>>>>>> BTW: initializing i in the constructor does not help (although
>>>>>> the program might have UB without doing so).
>>>
>>>>> This looks like a bug in gcc (4.3.0, in my case).
>>>
>>>> MSVC behaves the same way.
>>>
>>> I think that CockneyWinker has the solution in his posting:
>>>
>>> The problem is that the line Foo(i) is equivalent to Foo i, ...
>>>
>>> This seems to go against [5.2.3/1], but only if the line could
>>> not be parsed as a declaration. By [6.8/1] it seems that is can.
>>>
>>> Best
>>>
>>> Kai-Uwe Bux
>>
>> Yes, It seems so. When I change Foo(i) to Foo((int)i) or Foo(2)
>> then it behaves properly. But why does it need _extra_ typecast ?
>> can't it see that _i_ is declared as an int ? I am sorry, I don't
>> have much experience with C++. I still couldn't understand that
>> how Foo(i) is equal to *Foo i* ?
>
> Since you are allowed to declare a local variable with the same
> name as a member the compiler interprets this as such. Why it is
> allowed I don't know, but someone must have thought that it was
> good for something.
Inner scopes are allowed to declare names also present in outer
scopes. Class members are no different from other scopes.
The fact that a set of parenthesis are allowed is just because
*sometimes* they are needed. There are just no rules about not using
them when not needed.
Also, if Foo(i) were to work as "expected", it would also create a
temporary Foo inside the constructor. This is also pretty useless (and
strictly UB, as the outer i is still uninitialized).
I guess that the OP really wants a "delegating constructor" which will
be available in the next standard, C++0x. A constructor will be able
to call another constructor of the same class, in its initializer
list:
Foo() : Foo(1)
{ }
will set i to 1. Foo(i) will till be bad though!
Bo Persson