Topic: Defect Report: 3.8/9 example


Author: dsh@mvps.org (Doug Harrison)
Date: Mon, 5 Apr 2004 18:31:53 +0000 (UTC)
Raw View
Hyman Rosen wrote:

>Doug Harrison wrote:
>> Have you seen this:
>> http://www.comeaucomputing.com/iso/cwg_defects.html#89
>
>I just looked, and I don't particularly understand it.
>
>Since in C++ you're allowed to create a new object in the
>space of a non-const old one, the optimizer can't assume
>that the object in question is unchanged after a call to
>a function that might do that. LL's example which follows
>and is supposed to remain legal in fact exhibits undefined
>behavior, since it is creating a new object in the space
>of an old const object, which 3.8/9 disallows.

Paragraph 3.8/9 is concerned only with objects of static and automatic
storage duration, so it doesn't apply to LL's example, which was:

<q>
In addition, Lisa Lippincott pointed out the following example:

    void f( const bool * );
    void g();

    int main() {
       const bool *b = new const bool( false );
       f(b);
       if (*b)
          g();
    }

    void f( const bool *b ) {
       new ( const_cast<bool *>(b) ) const bool( true );
    }

The proposed wording in the paper would still permit this usage and
thus prevent an optimizer from eliminating the call to g().
</q>

It is the intent of the TC1 Issue 89 resolution to disallow the above
example, which is otherwise legal. IOW, it fixes the "proposed wording
in the paper" mentioned above.

>I get the feeling that these defect reports and proposed
>resolutions aren't getting the scrutiny they need, and
>we're going to be stuck with a worse standard than before
>because the patches are creating more errors.

I think this is a good one, because it prohibits modification of
objects declared const and rebinding of references. In particular, it
removes the placement new loophole, which I thought was overly cute. I
think with the TC1 change to 3.8/7, JP may be right that 3.8/9 is
redundant.

--
Doug Harrison
dsh@mvps.org

---
[ 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: John Potter <jpotter@falcon.lhup.edu>
Date: Thu, 1 Apr 2004 17:34:01 +0000 (UTC)
Raw View
[ Note: Forwarded to C++ Committee. -sdc ]

B const b;
void h () {
   b.~B();
   new (&b) const B;  // undefined behavior
   }

The commented line is ill-formed because there is no standard
conversion from from B const* to void*.

   new (&const_cast<B&>(b)) const B;

With the cast added, the whole paragraph may not be needed
because casting away the const and using the resulting
pointer could be undefined behavior for other reasons.  It
might be best to keep it anyway for clarity.

John


[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Thu, 1 Apr 2004 18:51:22 +0000 (UTC)
Raw View
John Potter wrote:
> With the cast added, the whole paragraph may not be needed
> because casting away the const and using the resulting
> pointer could be undefined behavior for other reasons.  It
> might be best to keep it anyway for clarity.

The paragraph is needed. If you have
     #include <memory>
     struct B { int i; B(int i) : i(i) { } };
     B const b(10);
     int main() { new(const_cast<B *>(&b))(19); }
nothing else in the standard prevents this from being legal.

---
[ 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: dsh@mvps.org (Doug Harrison)
Date: Fri, 2 Apr 2004 01:07:40 +0000 (UTC)
Raw View
Hyman Rosen wrote:

>John Potter wrote:
>> With the cast added, the whole paragraph may not be needed
>> because casting away the const and using the resulting
>> pointer could be undefined behavior for other reasons.  It
>> might be best to keep it anyway for clarity.
>
>The paragraph is needed. If you have
>     #include <memory>
>     struct B { int i; B(int i) : i(i) { } };
>     B const b(10);
>     int main() { new(const_cast<B *>(&b))(19); }
>nothing else in the standard prevents this from being legal.

Have you seen this:

http://www.comeaucomputing.com/iso/cwg_defects.html#89

<q>
89. Object lifetime does not account for reference rebinding
Section: 3.8  basic.life     Status: TC1     Submitter: AFNOR
Date: 27 Oct 1998
..
Proposed Resolution (10/00):

Add a new bullet to the list of restrictions in 3.8  basic.life
paragraph 7, following the second bullet ("the new object is of the
same type..."):

the type of the original object is not const-qualified, and, if a
class type, does not contain any non-static data member whose type is
const-qualified or a reference type, and
</q>

--
Doug Harrison
dsh@mvps.org

---
[ 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: jpotter@falcon.lhup.edu (John Potter)
Date: Fri, 2 Apr 2004 01:08:10 +0000 (UTC)
Raw View
On Thu, 1 Apr 2004 18:51:22 +0000 (UTC), hyrosen@mail.com (Hyman Rosen)
wrote:

> John Potter wrote:

> > With the cast added, the whole paragraph may not be needed
> > because casting away the const and using the resulting
> > pointer could be undefined behavior for other reasons.  It
> > might be best to keep it anyway for clarity.

> The paragraph is needed. If you have
>      #include <memory>
>      struct B { int i; B(int i) : i(i) { } };
>      B const b(10);
>      int main() { new(const_cast<B *>(&b))(19); }

I will assume a B before the (19).

> nothing else in the standard prevents this from being legal.

What does that mean?  Ill-formed is not legal, is undefined
behavior legal?  It is well-formed code which must be accepted.

You have removed the dtor, added a member, changed from a reference
cast to a pointer cast, oopsed the type, and dropped the const.  Which
of these removes something from the original in my post that was
covered elsewhere but not now?

I guess your changes were for no reason.  The undefined behavior
elswhere in the standard resulting from casting away constness and
modifying only applies to the object during its lifetime.  In your
example and in the original, the lifetime ended prior to the
modification.

I guess that we agree that the paragraph is needed.  If I missed
anything which makes it required for your example and not for
mine, please educate me.

John

---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 2 Apr 2004 19:03:46 +0000 (UTC)
Raw View
John Potter wrote:
> What does that mean?  Ill-formed is not legal, is undefined
> behavior legal?  It is well-formed code which must be accepted.

I mean that without the paragraph in question, the code would
be legal, and would not have undefined behavior.

> I guess your changes were for no reason.

Yes.

> I guess that we agree that the paragraph is needed.

You said that "With the cast added, the whole paragraph may not be
needed because casting away the const and using the resulting pointer
could be undefined behavior for other reasons." That sounds exactly
the opposite of agreeing that the paragraph is needed! I think it's
only this paragraph that prevents the space of a const object from
being reused for the creation of another object, and that this is a
restriction that needs to be kept.

---
[ 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: hyrosen@mail.com (Hyman Rosen)
Date: Fri, 2 Apr 2004 20:21:42 +0000 (UTC)
Raw View
Doug Harrison wrote:
> Have you seen this:
> http://www.comeaucomputing.com/iso/cwg_defects.html#89

I just looked, and I don't particularly understand it.

Since in C++ you're allowed to create a new object in the
space of a non-const old one, the optimizer can't assume
that the object in question is unchanged after a call to
a function that might do that. LL's example which follows
and is supposed to remain legal in fact exhibits undefined
behavior, since it is creating a new object in the space
of an old const object, which 3.8/9 disallows.

I get the feeling that these defect reports and proposed
resolutions aren't getting the scrutiny they need, and
we're going to be stuck with a worse standard than before
because the patches are creating more errors.

---
[ 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                       ]