Topic: Question on construction of anonymous temporary objects.


Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1997/09/24
Raw View
"Aaron S. Binns" <asbinn@rstcorp.com> writes:

|>  What are the rules on constructing anonymous temporary objects,
|>  especially in a function
|>  body?
|>
|>  I've noticed different behaviors between GCC 2.7.2 and SparcCompiler C++
|>  4.1.  Both compilers
|>  corretly parse a simple declaration.  However, introducing redunant
|>  parentheses makes the
|>  SparcWorks C++ compiler think that the variable being declared is a
|>  function call.

My impression is that g++ is right, and that you have found an error in
the SparcWorks C++ compiler.

|>  For example,:
|>
|>  class X
|>  {
|>  public:
|>    int m_x;
|>    X( ) : m_x(0) { }
|>    X( int x ) : m_x(x) { }
|>    void PrintX( ) { cout << "X::PrintX(): " << m_x << "\n"; }
|>  };
|>
|>  int foo( int p ) { return -p; }
|>
|>  int main( )
|>  {

    [...]

|>    X ( x5( 1 ) );    // GCC parses just as if it was "X x3(1)", but
|>  SparcCompiler C++ thinks
|>                      // that x3(1) is a function call and the return
|>  value is used to construct
|>                      // an anonymous temporary object using X::X(int).
|>                      // SparcCompiler gives an error here becuase there
|>  is no x5() function
|>                      // declared.

As far as I can tell, this should be a definition of x5, using the value
1 to initialize it.  If "x5( 1 )" is a function call, what is being
declared, and what is that initial "X" doing?

Similar logic holds for the remaining examples (which I've cut).

--
James Kanze    +33 (0)1 39 23 84 71    mailto: kanze@gabi-soft.fr
GABI Software, 22 rue Jacques-Lemercier, 78000 Versailles, France
        I'm looking for a job -- Je recherche du travail

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/09/26
Raw View
kanze@gabi-soft.fr (J. Kanze) writes:

>"Aaron S. Binns" <asbinn@rstcorp.com> writes:
>
>|>  I've noticed different behaviors between GCC 2.7.2 and SparcCompiler C++
>|>  4.1.  Both compilers
>|>  corretly parse a simple declaration.  However, introducing redunant
>|>  parentheses makes the
>|>  SparcWorks C++ compiler think that the variable being declared is a
>|>  function call.
>
>My impression is that g++ is right, and that you have found an error in
>the SparcWorks C++ compiler.

Yes, I agree.

>|>    X ( x5( 1 ) );    // GCC parses just as if it was "X x3(1)", but
>|>  SparcCompiler C++ thinks
>|>                      // that x3(1) is a function call and the return
>|>  value is used to construct
>|>                      // an anonymous temporary object using X::X(int).
>|>                      // SparcCompiler gives an error here becuase there
>|>  is no x5() function
>|>                      // declared.
>
>As far as I can tell, this should be a definition of x5, using the value
>1 to initialize it.  If "x5( 1 )" is a function call, what is being
>declared, and what is that initial "X" doing?

If "x5(1)" is a function call, then "X( x5(1) );" would be an
expression statement, not a declaration; it would construct an anonymous
object of type `X', initialized with the result of `x5(1)'.

However, the draft standard is clear about this one: such ambiguities
must be parsed as declarations, not as expressions.  See 6.8
[stmt.ambig].

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the
pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S.
Garp.

      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: "Aaron S. Binns" <asbinn@rstcorp.com>
Date: 1997/09/23
Raw View
What are the rules on constructing anonymous temporary objects,
especially in a function
body?

I've noticed different behaviors between GCC 2.7.2 and SparcCompiler C++
4.1.  Both compilers
corretly parse a simple declaration.  However, introducing redunant
parentheses makes the
SparcWorks C++ compiler think that the variable being declared is a
function call.

For example,:

class X
{
public:
  int m_x;
  X( ) : m_x(0) { }
  X( int x ) : m_x(x) { }
  void PrintX( ) { cout << "X::PrintX(): " << m_x << "\n"; }
};

int foo( int p ) { return -p; }

int main( )
{
  int a0 = 1;

  X x0;          // Both compilers parse this correctly, declaration of
x0.

  X x1(4)        // Both compilers parse these correctly, declaration of
x1 and x2 using
  X x2(a0);      // the X::X(int) conversion constructor.

  X (x3);        // Both compilers parse these correctly, declaration of
x3 and x4 using
  X ((x4));      // the X::X(int) conversion constructor.

  X ( x5( 1 ) );    // GCC parses just as if it was "X x3(1)", but
SparcCompiler C++ thinks
                    // that x3(1) is a function call and the return
value is used to construct
                    // an anonymous temporary object using X::X(int).
                    // SparcCompiler gives an error here becuase there
is no x5() function
                    // declared.
  X ( x6( a0 ) );   // Same situation, GCC declares x6 with the value of
a0 as the parameter
                    // to X::X(int).  SparcCompiler C++ constructs
anonymous temporary object
                    // of type X with the return value of calling
function x6(a0)
                    // SparcCompiler gives an error here becuase there
is no x6() function
                    // declared.

  X ( foo( a0 ) ).PrintX();  // Fails to compile with GCC, but
SparcCompiler C++ constructs
                             // an anonymous of type X using X::X(int)
with the value returned
                             // by calling foo(a0), then that anonymous
object's member function
                             // PrintX() is called.
  X ((foo(55))).PrintX();    // Same situation.

  return 0;
}

So, which compiler is doing the right thing?  I would hope it's GCC.  If
the SparcCompiler's
behavior is correct (with respect to the ANSI C++ DWP), then those
"redundant" parentheses
around the declarator are not so redunant -- they determine whether you
are declaring a
new object, or creating an anonymous temporary object.

Also, I checked out the grammar in the 12/96 DWP, and I couldn't see how
to parse an
anonymous object construction in the above manner.  If you have:

    T(foo(5)).MemberFunc( /* params */ );

Then "T(foo(5))" must be a postfix-expression.  By applying the
production:

    postfix-expression: postfix-expression '(' expression-listopt ')'

I see that "T" must be a postfix-expression, which reduces to a
primary-expression,
BUT a type name can't be a primary-expression (only if was preceeded by
'~').

Any insights would be appreciated.


Aaron
---
      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]