Thread View: comp.std.c++
7 messages
7 total messages
Started by ian (i.) willmott
Thu, 02 Nov 1995 11:43
Re: auto_ptr<T> as function return type
Author: ian (i.) willmott
Date: Thu, 02 Nov 1995 11:43
Date: Thu, 02 Nov 1995 11:43
84 lines
4111 bytes
4111 bytes
matt@cyclops5.berkeley.edu (Matt Austern) wrote:
>If a function returns an auto_ptr as an rvalue, it can't be used as
>the argument to a function that expects a non-const reference. There
>are ways to get around this, but they're all a bit clumsy.
So the problem is that rvalues cannot be passed as non-const reference
parameters? Can you call a non-const member function on an object rvalue?
(Other than the destructor, which presumably will be called implicitly.)
If so, isn't that an inconsistency, since member functions are passed an
implicit reference to the object they are called for?
What part, if any, of the following code is legal under the draft standard?
class X {
int i;
public:
X(int);
X(X &);
int get(void);
void set(int);
};
X f(void);
void g1(X &);
void g2(const X &);
void h(int i)
{
X x(f()); // 1 - illegal?
f().set(i); // 2 - legal?
g1(f()); // 3 - illegal?
g2(f()); // 4 - legal?
}
My Cfront v3.03 compiler (HP) calls line 3 an anachronism, but doesn't mind
the others. I couldn't tell from sections [basic.lval] and [dcl.init.ref]
of the April draft (maybe this has changed in the September version)
exactly what the rule is, but the ARM has this to say (p154):
If the initializer for a reference to type T is an lvalue of
type T ... the reference will refer to the initializer;
otherwise, if and only if the reference is to a const an object
of type T will be created and initialized with the initializer.
...
The distinction between references to consts and references to
non-consts is a major change from earlier definitions of C++.
The distinction was made to eliminate a major source of errors
and surprises. Earlier, all references could be initialized to
refer to temporary objects ...
Matt Austern:
>I don't know of any simply way to modify the definition of auto_ptr in
>the standard to avoid this difficulty: it seems to follow from the
>semantics of strict ownership.
It seems to me that this example tends to indicate that the prohibition of
non-const references to rvalues is a bad idea, at least for function
parameters. Section [basic.lval] suggests that you can in fact call
a non-const member function on a temporary object, so it's also inconsistent.
Why distinguish between member and non-member functions in this respect?
Surely there is a whole class of situations like this where the destructor
for a temporary has side effects which you may want to avoid or change by
modifying the object before it goes out of scope. I'm not sure what the ARM
means by "a major source of surprises"; if you pass a temporary as a reference
parameter, it's obviously going to evaporate after the function returns,
no matter what the function does or doesn't do to it.
I may be missing something here, but this seems like a really bad idea to me.
The ARM says "Naturally, this feature will be faded out of implementations
slowly, to avoid breaking working code", which sounds like an admission that
significant (and error-free) use has been made of it up until now. Maybe this
rule is what needs modification, rather than the definition of auto_ptr<T>.
Ian Willmott
Bell-Northern Research
Ottawa, Canada
(613)-763-9688
willmott@bnr.ca
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr<T> as function return type
Author: kanze
Date: Thu, 02 Nov 1995 23:24
Date: Thu, 02 Nov 1995 23:24
49 lines
2703 bytes
2703 bytes
In article <479thu$9k4@bcarh8ab.bnr.ca> "ian (i.) willmott"
<willmott@bnr.ca> writes:
|> Matt Austern:
|> >I don't know of any simply way to modify the definition of auto_ptr in
|> >the standard to avoid this difficulty: it seems to follow from the
|> >semantics of strict ownership.
|> It seems to me that this example tends to indicate that the prohibition of
|> non-const references to rvalues is a bad idea, at least for function
|> parameters. Section [basic.lval] suggests that you can in fact call
|> a non-const member function on a temporary object, so it's also inconsistent
.
|> Why distinguish between member and non-member functions in this respect?
|> Surely there is a whole class of situations like this where the destructor
|> for a temporary has side effects which you may want to avoid or change by
|> modifying the object before it goes out of scope. I'm not sure what the ARM
|> means by "a major source of surprises"; if you pass a temporary as a referen
ce
|> parameter, it's obviously going to evaporate after the function returns,
|> no matter what the function does or doesn't do to it.
The surprise occurs when you `accidentally' pass a temporary, such as
the result of an implicit conversion. Consider the following:
void
incr( int& i )
{
i ++ ;
}
unsigned j( 0 ) ;
incr( j ) ; // j unchanged!!!
I suppose the best rule would be to simply ban implicit conversions,
and make the programmer say what he means. But I rather suspect that
the amount of code that this would break will prohibit any such
change.
--
James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils en informatique industrielle --
-- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr<T> as function return type
Author: John Max Skaller
Date: Fri, 03 Nov 1995 04:02
Date: Fri, 03 Nov 1995 04:02
91 lines
3341 bytes
3341 bytes
"ian (i.) willmott" <willmott@bnr.ca> wrote:
>matt@cyclops5.berkeley.edu (Matt Austern) wrote:
>>If a function returns an auto_ptr as an rvalue, it can't be used as
>>the argument to a function that expects a non-const reference. There
>>are ways to get around this, but they're all a bit clumsy.
>
>So the problem is that rvalues cannot be passed as non-const reference
>parameters? Can you call a non-const member function on an object rvalue?
YES, if the rvalue is non-const..
>If so, isn't that an inconsistency, since member functions are passed an
>implicit reference to the object they are called for?
In my personal opinion, YES.
>What part, if any, of the following code is legal under the draft standard?
>
>class X {
> int i;
>public:
> X(int);
> X(X &);
> int get(void);
> void set(int);
>};
>
>X f(void);
>void g1(X &);
>void g2(const X &);
>
>void h(int i)
>{
> X x(f()); // 1 - illegal?
> f().set(i); // 2 - legal?
> g1(f()); // 3 - illegal?
> g2(f()); // 4 - legal?
>}
1 is illegal, can't bind a non-const ref to an rvalue,
even a non-const one.
2 is legal, you can call a non-const member function
on a non-const rvalue
3 is illegal for the same reason as 1
4 is legal
4 out of 4 right :-)
A more subtle question is whether
g1(const_cast<X&>(f()));
is legal, assuming g1 actually modifies its argument.
I think so -- all const objects can be
hardware write protected by the implementation,
but the rvalue f() involved here is non-const, so
it _is_ legal to modify it.
>It seems to me that this example tends to indicate that the prohibition of
>non-const references to rvalues is a bad idea, at least for function
>parameters. Section [basic.lval] suggests that you can in fact call
>a non-const member function on a temporary object, so it's also inconsistent.
>Why distinguish between member and non-member functions in this respect?
The argument is that it catches errors where you accidentally
modify a temporary (to no effect). In fact, doing exactly this
is a useful idiom, especially since the lifetime of temporaries
is now fixed (it wasn't in the ARM): it saves creating dummy
arguments where you don't WANT modifications to persist in
some more permanent object.
So there's a trade off I think ought to be a quality
of implementation issue.
--
John Max Skaller voice: 61-2-566-2189
81 Glebe Point Rd fax: 61-2-660-0850
GLEBE NSW 2037 email: maxtal@suphys.physics.oz.au
AUSTRALIA email: skaller@maxtal.com.au
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr<T> as function return type
Author: Ralph Shnelvar
Date: Sat, 04 Nov 1995 00:30
Date: Sat, 04 Nov 1995 00:30
26 lines
1243 bytes
1243 bytes
kanze <kanze@lts.sel.alcatel.de> wrote: > >The surprise occurs when you `accidentally' pass a temporary, such as >the result of an implicit conversion. Consider the following: . . . > >I suppose the best rule would be to simply ban implicit conversions, >and make the programmer say what he means. But I rather suspect that >the amount of code that this would break will prohibit any such >change. Yesterday, on compuserve I said almost exactly the same thing. Let there be a #pragma or -something- that turns off this awful creation of temporaries. Ralph --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr<T> as function return type
Author: law
Date: Mon, 06 Nov 1995 10:45
Date: Mon, 06 Nov 1995 10:45
53 lines
2728 bytes
2728 bytes
In <47ec58$3t3@meg.tesser.com>, ralphs@tesser.com (Ralph Shnelvar) writes:
>
>kanze <kanze@lts.sel.alcatel.de> wrote:
>
>>The surprise occurs when you `accidentally' pass a temporary, such as
>>the result of an implicit conversion. Consider the following:
>.. . .
>>
>>I suppose the best rule would be to simply ban implicit conversions,
>>and make the programmer say what he means. But I rather suspect that
>>the amount of code that this would break will prohibit any such
>>change.
>
>Yesterday, on compuserve I said almost exactly the same thing.
>
>Let there be a #pragma or -something- that turns off this awful
>creation of temporaries.
>
>Ralph
Perhaps the *best* rule would be one that permits the initializer for a
non-const T& to be *any* object of type T, not just lvalues? It seems
there's a clear distinction between these three cases:
void incr( int& );
int ok();
double notOk;
double maybe();
incr( ok() ); // This is OK.
incr( notOk ); // This isn't.
incr( maybe() ); // Why not?
In the first case, the reference is clearly bound to the same object that
the programmer specified as the initializer. In the second, the reference
is clearly bound to a different object. In the third, it's a different
object but I don't think it much matters.
I would like to see a rule that prohibits only cases where the binding of
the reference requires the conversion from a non-temporary initializer
to a temporary object. At the least, I think it should be OK if no
conversions are required.
In other words, is it possible the baby was thrown out with the bathwater
when the "notOK" problem was fixed way back when? Or is there no way
(syntactically or otherwise) to loosen up the rules just a little?
Bill Law
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr<T> as function return type
Author: Sam Fenster
Date: Tue, 07 Nov 1995 04:44
Date: Tue, 07 Nov 1995 04:44
55 lines
3713 bytes
3713 bytes
> "ian (i.) willmott" <willmott@bnr.ca> writes:
>> It seems to me that this example tends to indicate that the prohibition of
>> non-const references to rvalues is a bad idea, at least for function
>> parameters. Section [basic.lval] suggests that you can in fact call a
>> non-const member function on a temporary object, so it's also inconsistent
> .
>> Why distinguish between member and non-member functions in this respect?
>
>> Surely there is a whole class of situations like this where the destructor
>> for a temporary has side effects which you may want to avoid or change by
>> modifying the object before it goes out of scope. I'm not sure what the ARM
>> means by "a major source of surprises"; if you pass a temporary as a
>> reference parameter, it's obviously going to evaporate after the function
>> returns, no matter what the function does or doesn't do to it.
kanze <kanze@lts.sel.alcatel.de> writes:
> The surprise occurs when you `accidentally' pass a temporary, such as the
> result of an implicit conversion. Consider the following:
> void incr (int& i) {i ++;}
> unsigned j (0);
> incr (j); // j unchanged!!!
>
> I suppose the best rule would be to simply ban implicit conversions, and
> make the programmer say what he means. But I rather suspect that the amount
> of code that this would break will prohibit any such change.
There is a perfect solution which I would be happy if someone proposed
officially. It prevents the above pitfall, yet it allows temporaries to be
modified. Also, it breaks no code since (I think -- check me out on this) it
merely relaxes the rules:
- First of all, get rid of the worse-than-useless restriction that disallows
binding non-const references to temporaries.
- Second (and last), add a rule that says that there is no implicit conversion
of a temporary to a non-const reference.
The intent of the currently existing rule is to prevent code from mistakenly
modifying the result of an implicit conversion instead of modifying the
original object. This pitfall is the only reason I know of for prohibiting
functions modifying temporaries. Witness the fact that the prohibition does
not extend to temporaries invoking non-const member functions since implicit
conversions are not done to objects invoking member functions.
The above proposed changes will still prevent this pitfall, by preventing the
implicit conversion to a temporary rather than preventing the binding of a
temporary. The new rule will allow temporaries to be modified, which is
important to many designs, including auto_ptr<>. And these changes will not
break existing code, since they only disallow the implicit conversion when the
resulting binding would be disallowed under current rules.
---
[ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
Contact address: std-c++-request@ncar.ucar.edu. The moderation policy
is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Re: auto_ptr<T> as function return type
Author: jodle
Date: Wed, 15 Nov 1995 07:39
Date: Wed, 15 Nov 1995 07:39
18 lines
1189 bytes
1189 bytes
Ralph Shnelvar (ralphs@tesser.com) wrote: : Let there be a #pragma or -something- that turns off this awful : creation of temporaries. I think it would be a bad thing for the standard to prescribe what pragmas a compiler will support. It's sufficient that it doesn't preclude them. Furthermore, privately declared copy constructors work wonders in this regard. I've found that where programmers say they don't want temporaries generated, what they really don't want is their copy implementations stressed. --- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu. Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is summarized in http://dogbert.lbl.gov/~matt/std-c++/policy.html. ]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads