Topic: Does the proposed resolution to core issue 232 allow null references? [Was: Proposal: finally allow "void main()"]
Author: johnchx2@yahoo.com
Date: Wed, 30 Mar 2005 23:06:08 CST Raw View
Victor Bazarov wrote:
> "William M. Miller" wrote:
> > [..] We wanted to deal with this more generally, as well as
> > the one-past-the-end pointer; that is why the proposed wording
> > introduces the "empty lvalue" and forbids applying the
> > lvalue-to-rvalue conversion to it.
>
> OK, thanks.
>
> What I get from all this is that
>
> sometype *p = 0;
> sometype &r = *p;
>
> is not ill-formed, only produces undefined behaviour. Correct?
That is correct. That is well-formed but undefined today, and would be
well-formed but undefined if the committee's proposal is accepted.
> Or does it? Essentially, 'r' cannot be "used" in any way, except
> to take its address. Am I right?
No. You were right the first time. The initialization is undefined.
It is undefined under the current standard, and it is undefined under
the proposals.
> > As I said, though, this
> > change does not affect the status of "null references" at all.
> > The only thing that changes with references is the explicit
> > acknowledgment that they can be bound to "pre-natal" and
> > "post-mortem" objects (which can already be referred to by
lvalues).
>
> OK. And at the same time lvalue-to-rvalue conversion on those
> objects leads to undefined behaviour, yes?
Yes, just like any lvalue refering to an object before or after its
lifetime. I.e. giving such an lvalue a name changes nothing. Notice,
by the way, that the only change here is allowing a reference to be
*initialized* with such an object. Nothing in the current standard
prevents you from initializing a reference with a live object, then
ending that object's lifetime.
It begins to sound like you've been relying on guarantees about the
validity of referenced objects that the language has never really
offered.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: ben-public-nospam@decadentplace.org.uk (Ben Hutchings)
Date: Thu, 31 Mar 2005 05:06:54 GMT Raw View
Victor Bazarov wrote:
> "William M. Miller" wrote:
>> [..] We wanted to deal with this more generally, as well as
>> the one-past-the-end pointer; that is why the proposed wording
>> introduces the "empty lvalue" and forbids applying the
>> lvalue-to-rvalue conversion to it.
>
> OK, thanks.
>
> What I get from all this is that
>
> sometype *p = 0;
> sometype &r = *p;
>
> is not ill-formed, only produces undefined behaviour. Correct?
Correct.
> Or does it? Essentially, 'r' cannot be "used" in any way, except
> to take its address. Am I right?
No, but the statement will be true if you substitute *p for r. r's
initialisation has undefined behaviour, so nothing can be said about
its use.
> So we essentially allow the existence of such reference whose
> addressed object is "not there" as it were.
<snip>
No. References and lvalues are not the same thing, and it's already
established that not all lvalues can be bound to references (bitfields
can't).
--
Ben Hutchings
Humans are not rational beings; they are rationalising beings.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Victor Bazarov" <v.Abazarov@comAcast.net>
Date: Fri, 1 Apr 2005 11:50:33 CST Raw View
johnchx2@yahoo.com wrote:
> [..]
> It begins to sound like you've been relying on guarantees about the
> validity of referenced objects that the language has never really
> offered.
Really? What makes you think that? I am genuinely interested, please
indulge me with your explanation. Thank you.
V
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: johnchx2@yahoo.com
Date: Fri, 1 Apr 2005 23:36:17 CST Raw View
Victor Bazarov wrote:
> johnchx2@yahoo.com wrote:
> > [..]
> > It begins to sound like you've been relying on guarantees
> > about the validity of referenced objects that the language
> > has never really offered.
>
>
> Really? What makes you think that? I am genuinely interested,
> please indulge me with your explanation. Thank you.
Of course. For example:
> I will now have to begin to write code like this:
>
> void foo(int& ri) {
> if (&ri != 0) // it's a null reference
> ;// do something to use 'ri'
> }
>
> Because this seems where the language is headed. Pity.
Perhaps I'm over-interpreting, but the above reads to me as if you
believed that the language (currently) guarantees that the reference ri
denotes a live object in any well-formed program. Am I
misunderstanding?
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Sat, 2 Apr 2005 00:39:51 CST Raw View
* johnchx2@yahoo.com -> Victor Bazarow:
>
> > I will now have to begin to write code like this:
> >
> > void foo(int& ri) {
> > if (&ri != 0) // it's a null reference
> > ;// do something to use 'ri'
> > }
> >
> > Because this seems where the language is headed. Pity.
>
> Perhaps I'm over-interpreting, but the above reads to me as if you
> believed that the language (currently) guarantees that the reference ri
> denotes a live object in any well-formed program. Am I
> misunderstanding?
When the goal is to clear up something, unclear terms such as "well-formed"
and "live" are counter-productive; they can be useful, however, when the
goal is to muddy the waters.
As far as I understand "well-formed" _nothing_ about run-time behavior is
guaranteed by well-formed'ness of the program text.
In the current language there is a guarantee that 'ri' above is not a
null-reference, 8.3.2/4. The same paragraph also a guarantees that it refers
to a valid object, "shall be initialized to refer to a valid object", and
parameters are initialized. The word "live" doesn't occur in the standard.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Victor Bazarov" <v.Abazarov@comAcast.net>
Date: Sat, 2 Apr 2005 12:15:48 CST Raw View
johnchx2@yahoo.com wrote:
> Victor Bazarov wrote:
>> johnchx2@yahoo.com wrote:
>>> [..]
>>> It begins to sound like you've been relying on guarantees
>>> about the validity of referenced objects that the language
>>> has never really offered.
>>
>>
>> Really? What makes you think that? I am genuinely interested,
>> please indulge me with your explanation. Thank you.
>
> Of course. For example:
>
>> I will now have to begin to write code like this:
>>
>> void foo(int& ri) {
>> if (&ri != 0) // it's a null reference
>> ;// do something to use 'ri'
>> }
>>
>> Because this seems where the language is headed. Pity.
>
> Perhaps I'm over-interpreting, but the above reads to me as if you
> believed that the language (currently) guarantees that the reference
> ri denotes a live object in any well-formed program. Am I
> misunderstanding?
Doesn't it? I mean, doesn't language (currently) guarantee that the
reference 'ri' is initialised to refer to a valid object? Are you
saying that currently it's not so, and my regrets about "where the
language is headed" were unfounded since it's already "there"?
It is impossible to initialise a function argument of type 'a reference
to T' with anything except an object of T or an object convertible to T
(please see 8.5.3). [As Mike has pointed out, the language is still going
to enforce that, so my fear that the language is headed in the wrong
direction has no foundation, as I know realize]
V
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: johnchx2@yahoo.com
Date: Mon, 4 Apr 2005 21:04:40 CST Raw View
Victor Bazarov wrote:
> I mean, doesn't language (currently) guarantee that the
> reference 'ri' is initialised to refer to a valid object?
I guess it boils down to what you mean by "guarantee." I can see two
possible meanings:
Guarantee #1: "Proposition Truth Value" - the language "guarantees" a
proposition when it ensures that the proposition is always true.
Guarantee #2: "Permission to Fail" - the language "guarantees" a
proposition when it specifies that program failure due to reliance upon
the guarantee is not an error.
"Permission to Fail" is, of course, essentially the same as "undefined
behavior" in C++. If that's the kind of guarantee you mean, then yes,
the language guarantees that the reference is initialized to refer to a
valid object. It doesn't guarantee that that is true, but it absolves
us of responsibility for errors arising out of situations in which it
isn't true.
I (mis-)understood you to be saying that the current language offered
Guarantee #1 because you suggested you might have to add run-time tests
to detect and handle situations in which the proposition wasn't true
(which you might want to do in the presence of Guarantee #2, if you
wanted to handle the error "gracefully," but which would be strictly
redundant in the presence of Guarantee #1).
> It is impossible to initialise a function argument of type
> 'a reference to T' with anything except an object of T
> or an object convertible to T (please see 8.5.3).
I'd say, "It is undefined behavior" rather than "It is impossible," but
beyond that semantic quibble, yes, we're agreed on this too.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: "Victor Bazarov" <v.Abazarov@comAcast.net>
Date: Tue, 29 Mar 2005 23:03:26 CST Raw View
"William M. Miller" wrote:
> [..] We wanted to deal with this more generally, as well as
> the one-past-the-end pointer; that is why the proposed wording
> introduces the "empty lvalue" and forbids applying the
> lvalue-to-rvalue conversion to it.
OK, thanks.
What I get from all this is that
sometype *p = 0;
sometype &r = *p;
is not ill-formed, only produces undefined behaviour. Correct?
Or does it? Essentially, 'r' cannot be "used" in any way, except
to take its address. Am I right? So we essentially allow the
existence of such reference whose addressed object is "not there"
as it were. What is it if not a "null reference"?
Please clarify.
> As I said, though, this
> change does not affect the status of "null references" at all.
> The only thing that changes with references is the explicit
> acknowledgment that they can be bound to "pre-natal" and
> "post-mortem" objects (which can already be referred to by lvalues).
OK. And at the same time lvalue-to-rvalue conversion on those
objects leads to undefined behaviour, yes? I mean, if we try to
apply an operation that requires fetching the value of an object
that hasn't been constructed or has been destroyed, then KABOOOM!
Doesn't really change a thing WRT "null references", does it?
V
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (Llewelly)
Date: Tue, 22 Mar 2005 20:40:13 GMT Raw View
v.Abazarov@comAcast.net ("Victor Bazarov") writes:
> "Llewelly" <llewelly.at@xmission.dot.com> wrote...
> > v.Abazarov@comAcast.net ("Victor Bazarov") writes:
> >
> >> "Daryle Walker" <thedl0-usenet1@yahoo.com> wrote...
> >> > Declaring a program's "main" function to have a "void" return type is a
> >> > favorite of many, especially newbies. [...]
> >>
> >> But so are null references. You don't see anybody proposing changing the
> >> language to accommodate them, do you?
> >
> > See the proposed resolution for core issue 232. It appears to allow:
> >
> > T* p= 0;
> > T& r= *p;
>
> Nothing of the sort. It mentions 'p = 0; *p;'
When I originally read the resolution, I assumed '*p;' required the
lvalue-to-rvalue conversion, and initializing a reference did not
require the lvalue-to-rvalue conversion.
> which will still give
> undefined behaviour.
[snip]
The 'Note' part of the proposed resolution contains:
# [Note: a pointer to an incomplete type (other than cv void) can be
# dereferenced. The lvalue thus obtained can be used in limited ways (to
# initialize a reference, for example); this lvalue must not be
# converted to an rvalue, see 4.1 conv.lval.end note]'
That's non-normative, but so is your 'p = 0; *p;' quote. The changes
to normative text only mention undefined behavior in the case of
lvalue-to-rvalue conversion:
# 3. Add the indicated words to 4.1 conv.lval paragraph 1:
#
# If the object to which the lvalue refers is not an object of type
# T and is not an object of a type derived from T, or if the object
# is uninitialized, or if the lvalue is an empty lvalue (5.3.1
# expr.unary.op), a program that necessitates this conversion has
# undefined behavior.
So, the question seems to be: Does 'T& r= *p;' require an
lvalue-to-rvalue conversion? When I first read resolution, I
assumed not. Now, due to your post, I'm re-reading the resolution,
and I'm re-reading 8.5.3 . I admit I don't fully understand
either, but in the first bullet of 8.5.3/5, I find:
# -- If the initializer expression
#
# -- is an lvalue (but is not a bit-field), and "cv1 T1" is
# reference-compatible with "cv2 T2," or
#
# -- has a class type (i.e., T2 is a class type) and can be
# implicitly converted to an lvalue of type "cv3 T3," where "cv1
# T1" is reference-compatible with "cv3 T3" 92) (this conversion
# is selected by enumerating the applicable conversion functions
# (13.3.1.6) and choosing the best one through over-load
# resolution (13.3)), then the reference is bound directly to the
# initializer expression lvalue in the first case, and the
# reference is bound to the lvalue result of the conversion in
# the second case. In these cases the reference is said to bind
# directly to the initializer expression. [Note: the usual
# lvalue-to-rvalue (4.1), array-to-pointer (4.2), and
# function-to-pointer (4.3) standard conversions are not needed,
# and therefore are suppressed, when such direct bindings to
# lvalues are done. ]
So I would appreciate it if you would explain why you think
T* p= 0;
T& r= *p;
either requires the lvalue-to-rvalue conversion when initializing the
reference, or would have undefined behavior for some other reason,
if the proposed resolution to core issue 232 was accepted as it
stands today.
(Despite all appearances, I'm *not* in favor of extending the standard
to support null references.)
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]
Author: johnchx2@yahoo.com
Date: Wed, 23 Mar 2005 13:46:10 CST Raw View
Llewelly wrote:
> So I would appreciate it if you would explain why you think
>
> T* p= 0;
> T& r= *p;
>
> either requires the lvalue-to-rvalue conversion when initializing
> the reference, or would have undefined behavior for some other
> reason, if the proposed resolution to core issue 232 was accepted
> as it stands today.
If 232 is accepted and 453 isn't, then 8.3.2 still says "A reference
shall be initialized to refer to a valid object or function." The
initialization above does not fulfill this requirement. If 453 is
accepted, then 8.3.2 would say "If an lvalue to which a reference is
directly bound designates neither an existing object or function of an
appropriate type, nor a region of memory of suitable size and alignment
to contain an object of the reference's type, the behavior is
undefined." Either way, it's UB.
The committee seems to be bending over backwards to make sure that the
"empty lvalue" does NOT give rise to null references.
---
[ 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://www.jamesd.demon.co.uk/csc/faq.html ]