Shreyas
Shreyas

Reputation: 351

Output behaviour in different compilers

#include <iostream>

class Y
{
      public:
             Y();
};

class X
{
      public:
             void foo() {}
             friend Y::Y();

             X()
             {
                    Y::Y();  //Statement 1
             }
};

Y::Y()
{
   std::cout << "Hello";
}

int main()
{
    X a;
    Y::Y();      //Statenent 2
}

The above program produces the output HelloHello on Dev c++ and codepad. But when i run on Code::Blocks it gives error remove the reduntant Y::

If i replace statement 1 and 2 withh Y(); , the program produces the output in all 3. Why so?

Upvotes: 1

Views: 213

Answers (3)

harper
harper

Reputation: 13690

If i replace statement 1 and 2 withh Y(); , the program produces the output in all 3. Why so?

The output is produced by calling the function Y::Y(). You do this either in the constructor of an instance of the class X or by calling the function directly.

But let's look at the variant "Statement 1". The code

int main ()
{
    X a;
}

creates an unused variable. The compiler might optimize it away. In that case the constructor is not called. That's dependend on the compiler and the actual options used. When you call the function Y::Y() directly it can't be optimized away and you get always the output.

Upvotes: 0

pqnet
pqnet

Reputation: 6588

Y::Y(); is wrong in C++. It shouldn't be allowed even by Dev C++.

If you mean to call the constructor for class Y you just have to create an object of type Y, e.g.

Y my; //creates an object named my of type Y
Y my = Y(); //same as above
Y(); // creates a temporary object which is destroyed in the following line

Upvotes: 0

user743382
user743382

Reputation:

Inside every class X, X can be used to refer to that class. This allows, for example,

struct X {
  struct Y {
    static int f();
  };
};
int X::Y::f() {
  Y y;
  return 0;
}
int main() {
  return X::Y::f();
}

to work, even though Y appears to not be in scope inside the definition of X::Y::f.

The way the standard specifies this has changed. In the original C++ standard, Y was simply treated as a member of ::X::Y, and meant ::X::Y. This interpretation made it impossible to refer to a constructor, since X::X was always a type. As a result, in the first TC, the standard was changed to make X::X refer to a type's constructor (in most cases).

One of your compilers implements the original C++ rules, the other the newer rules.

By the original rules, Y::Y(); is just peachy. You're constructing a type. That type has an accessible constructor, so there is no issue.

By the newer rules, Y::Y(); is an error. You're calling a constructor, and you're not allowed to explicitly call a constructor.

For those interested, this is core language issue 147.

Upvotes: 4

Related Questions