Topic: C++ seems to allow an implicit const-->non-const conversion under


Author: alfps@start.no ("Alf P. Steinbach")
Date: Thu, 31 Aug 2006 17:26:21 GMT
Raw View
* Christoph Schulz:
> Consider following C++ program:
>=20
> #include <iostream>
> using namespace std;
>=20
> struct Test
> {
>  Test &nonconst_this;
>  int value;
>  Test () : nonconst_this (*this), value (1) {}
>  void inc () {++value;}
>  void inc () const {nonconst_this.inc ();}
> };
>=20
> int main ()
> {
>  const Test t;
>  cout << t.value << endl; // prints 1
>  t.inc ();
>  cout << t.value << endl; // prints 2 with the compilers I used
>  // (MSVC++ 2005, Comeau 4.3.8 BETA)
> }
>=20
> My question is whether the program produces undefined behaviour or not
> with regard to the current C++ standard.

Formally, yes, because =A77.1.5.1/4: "... any attempt to modify a=20
[non-mutable] const object during its lifetime (3.8) results in=20
undefined behavior".


> As far as I can see this
> program is able to perform a const-->non-const conversion without
> specifying a cast, namely by the use of a non-const reference
> initialized by the constructor. That is alarming because implicit
> const-->non-const conversions are evil. However, provided the program
> above does compile cleanly as it does not violate any diagnosable rule
> (what I assume), I don't see any way to catch the obviously existing
> error at compile time.

Some compilers warn about using 'this' in constructor initialization=20
lists.  However, that feature is generally most unwelcome.  In practice=20
the programmer using 'this' in an initialization list knows what s/he is=20
doing.


> A possibility would be perhaps to add const constructors with the
> special rule that member initialization is allowed although the "this"
> pointer is of type T const* instead of T*.
>=20
> What do you think?

There's no way to prevent a programmer from shooting her or his own=20
feet, one way or another.

--=20
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.comeaucomputing.com/csc/faq.html                      ]





Author: Ron Natalie <ron@spamcop.net>
Date: Thu, 31 Aug 2006 12:38:47 CST
Raw View
Christoph Schulz wrote:
> Consider following C++ program:
>
> #include <iostream>
> using namespace std;
>
> struct Test
> {
>  Test &nonconst_this;
>  int value;
>  Test () : nonconst_this (*this), value (1) {}

During the construction of an object, the constness of *this is
turned off (otherwise you could never really initialize a const).
Since you keep a reference (a pointer would have done the same)
to the non-const *this at this point, you are explicitly busting
const.

>
> My question is whether the program produces undefined behaviour or not
> with regard to the current C++ standard.

Changes once the constructor finishes are indeed undefined behavior.

> As far as I can see this
> program is able to perform a const-->non-const conversion without
> specifying a cast, namely by the use of a non-const reference
> initialized by the constructor. That is alarming because implicit
> const-->non-const conversions are evil.

There's nothing implicit.  You explicitly violated the rules by leaving
a pointer around to *this outside an appropriate context.   A large
number of compilers will actually give you a warning about the use
of the "this" pointer being used during construction like this.

Your solution is unworkable.   You would have to allow the this pointer
(or reference to *this) to be passed to other functions (either
explicitly as an argument, or implicitly as being a call to another
non-const non-static member function in the object).   These
functions would be succeptable to the same sort of const breaking
if they stored the pointer/reference to this somewhere that persists
past the duration of the construction.

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: alfps@start.no ("Alf P. Steinbach")
Date: Thu, 31 Aug 2006 17:37:05 GMT
Raw View
* Florin Neamtu:
> The program is not valid C++ as the "this" pointer cannot be used in
> the initializer list.

Please quote the relevant chapter and verse.

--
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.comeaucomputing.com/csc/faq.html                      ]





Author: ron@spamcop.net (Ron Natalie)
Date: Thu, 31 Aug 2006 20:22:21 GMT
Raw View
Florin Neamtu wrote:
> The program is not valid C++ as the "this" pointer cannot be used in
> the initializer list.

Yes it is.

> In the scope of the initializer list the object is not yet constructed
> and any reference to it is invalid; such your code passes a pointer to
> an unconstructed object and the result is undefined according to the
> standard.

Is not.

While it is dangerous to be passing around pointers to objects still
under construction to unwary recipients, it is not prohibited.

---
[ 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.comeaucomputing.com/csc/faq.html                      ]





Author: kristov@arcor.de (Christoph Schulz)
Date: Thu, 31 Aug 2006 16:05:05 GMT
Raw View
Consider following C++ program:

#include <iostream>
using namespace std;

struct Test
{
 Test &nonconst_this;
 int value;
 Test () : nonconst_this (*this), value (1) {}
 void inc () {++value;}
 void inc () const {nonconst_this.inc ();}
};

int main ()
{
 const Test t;
 cout << t.value << endl; // prints 1
 t.inc ();
 cout << t.value << endl; // prints 2 with the compilers I used
 // (MSVC++ 2005, Comeau 4.3.8 BETA)
}

My question is whether the program produces undefined behaviour or not
with regard to the current C++ standard. As far as I can see this
program is able to perform a const-->non-const conversion without
specifying a cast, namely by the use of a non-const reference
initialized by the constructor. That is alarming because implicit
const-->non-const conversions are evil. However, provided the program
above does compile cleanly as it does not violate any diagnosable rule
(what I assume), I don't see any way to catch the obviously existing
error at compile time.

A possibility would be perhaps to add const constructors with the
special rule that member initialization is allowed although the "this"
pointer is of type T const* instead of T*.

What do you think?

Regards,
  Christoph

---
[ 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.comeaucomputing.com/csc/faq.html                      ]