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
]