Topic: [OT]More Questions...
Author: "Homer Meyer" <homer@cqg.com>
Date: 2000/04/03 Raw View
Janusz Szpilewski wrote in message
<38E8529F.C1B2FBEA@vz.cit.alcatel.fr>...
>Homer Meyer wrote:
>>
>
>> That's right. The compiler is allowed to optimize it away.
Conceptually
>> though, the temporary is created every time.
>>
>
>Ok, I may agree that conceptually in functional type conversion a
>temporary object is created every time, even if actually it is not
>created (just a "zero" element in the set). But this is a general
>definition trying to cover all possible cases.
>
>
>However the the subject of the discussion is the basic and exact case
>of:
>
>Type x = Type();
>
>
>I would like to present some more paragraphs from the standard (I
cannot
>give the exact references as it comes from a draft, but I hope they can
>be easily found) telling when temporary object are created:
>
>"Temporaries of class type are created in various contexts: binding an
> rvalue to a reference (_dcl.init.ref_), returning an
rvalue
> (_stmt.return_), a conversion that creates an rvalue
(_conv.lval_,
> _expr.static.cast_, _expr.const.cast_, _expr.cast_), throwing
an
> exception (_except.throw_), entering a handler (_except.handle_),
and
> in some initializations (_dcl.init_)."
You missed the very next sentence which is relevant. (btw, this is from
12.2 paragraph 1)
"Even when the creation of the temporary is avoided (12.8), all the
semantic
restrictions must be respected as if the temporary object was created.
[Example: even if the copy constructor is not called all the semantic
restrictions, such as accessibility (clause 11), shall be satisfied.]"
>It is clearly stated "in some initaializations". The definition is
>followed by some examples like:
>
>X b = f(X(2));
>a = f(a);
>
>With which I completely agree that a temporary object is created there
>and if not, it is an optimization issue.
>
>
>And the section about initializators (_dcl.init_) says:
>
>"The initialization that occurs in new expressions (_expr.new_),
> static_cast expressions (_expr.static.cast_), functional notation
type
> conversions (_expr.type.conv_), and base and member
initializers
> (_class.base.init_) is called direct-initialization and is
equivalent
> to the form T x(a); "
>
>
>In this case it is precisely said that _initialization_ with functional
>notation type conversions is exivalent to T x(a);
>
> T x = T(a); <==> T x(a);
Going to the section on functional type conversions: (5.2.3 paragraph 1)
"A simple-type-specifier followed by a parenthesized expression-list
constructs a value of the specified type given the expression list. If
the
expression list is a single expression, the type conversion expression
is
equivalent (in definedness, and if defined in meaning) to the
corresponding
cast expression. If the simple-type-specifier specifies a class type,
the
class type shall be complete. If the expression list specifies more
than a
single value, the type shall be a class with a suitably declared
constructor, and the expression T(x1, x2, ...) is equivalent in effect
to
the declaration T t( x1, x2, ... ); for some invented temporary variable
t,
with the result being the value of t as an rvalue."
>I hope no one claims that T x(a); creates a temporary object.
Well according to the above it could be interpreted that way.
<rest SNIPped>
Looking at 8.5 paragraph 12:
"The initialization that occurs in argument passing, function return,
throwing an exception, handling an exception, and brace-enclosed
initializer
lists is called copy-initialization and is equivalent to the form T x =
a;"
And 8.5 paragraph 14:
"-- If the initialization is direct-initialization, or if it is
copy-initialization where the cv-unqualified version of the source type
is
the same class as, or a derived class of, the class of the destination,
constructors are considered. The applicable constructors are
enumerated,
and the best one is chosen through overload resolution. The constructor
so
selected is called to initialize the object, with the initializer
expression(s) as its argument(s). If no constructor applies, or the
overload resolution is ambiguous, the initialization is ill-formed."
>From these quotes and the ones that you presented, I am beginning to
think
that you may be right, so I have cross-posted this to
comp.lang.c++.moderated and comp.std.c++ in the hopes that some of the
language lawyers can clear this up for us.
Is
T x = T(x1,x2,...);
equivalent to
T x(x1,x2,...);
or
In the first case, is a temporary conceptionally created (compiler may
optimize it away) and the value then copied via the copy constructor?
It seems to make a difference which way it is done because of access
specifiers on the constructors. So, I have created a bit of test code
to
see how my compiler does it. I know this doesn't prove anything about
the
standard, only my compiler vendor's implementation.
class A {
int v;
A( const A& ); // copy constructor is private and unimplemented
public:
A( int x ) : v(x) {}
};
int main() {
A a = A(1); // illegal?
A b = 2; // illegal?
A c(3);
}
My compiler (VC++ 5.0) produces:
- an error on "A a = A(1);" This the expected behaviour if a temporary
is
created and the copy constructor is called.
- no error on "A b = 2;" This was a surprise after the first error.
Now,
I'm really confused.
- no error on "A c(3);" This was just as I expected.
I hope you nice folks in comp.lang.c++.moderated and comp.std.c++ can
clear
Janusz and I up. We seem to have come to a dead end in comp.lang.c++.
Homer
[ 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 news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]