Topic: Qualification conversions & const safety


Author: Greg McGary <gkm@magilla.cichlid.com>
Date: 1995/11/09
Raw View
According to sec. 4.4: Qualification conversions, paragraph 3, the
following is NOT a const-safe conversion:

 char * *  --> char const * *

whereas this is safe:

 char * *  --> char const *const *

Why?  I don't see how *adding* `const' an any level of a multi-level
pointer could lessen safety.

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





Author: martelli@cadlab.it (Alex Martelli)
Date: 1995/11/10
Raw View
Greg McGary <gkm@magilla.cichlid.com> writes:

>According to sec. 4.4: Qualification conversions, paragraph 3, the
>following is NOT a const-safe conversion:

> char * *  --> char const * *

>whereas this is safe:

> char * *  --> char const *const *

>Why?  I don't see how *adding* `const' an any level of a multi-level
>pointer could lessen safety.

It's very un-intuitive (keeps coming up in various guises in c.l.c++,
too -- and comp.sather, comp.object, comp.<whatever>...:-), but
nevertheless true.  Consider this example:

 const char array[] = "Hello";
 void naive(const char **p) {
     *p = &array[0];
 }
 void tricky(char **p) {
     naive(p);
 }
 //...
 char *q;
 tricky(&q);
 *q='P';

What's going on here?  Const safety is clearly violated, since
the last statement tries to change the value of a character
that has been defined as constant; there were no casts anywhere;
_where_ was our safety compromised?

Answer: in tricky()'s call on naive(), where a char** was
transformed into a const char**.  That transformatoin is not safe.

Why?  Because transforming X*->Y* is ok iff Y can be everywhere
substituted for X (Liskov principle); and a "char const *"
cannot be _everywhere_ substituted for a "char *" -- in
particular, it cannot be when it's dereferenced and the
result _changed_.


Alex
--
DISCLAIMER: these are TOTALLY personal opinions and viewpoints, NOT connected
in any way with my employer, nor any other organization or individual!
Email: martelli@cadlab.it                            Phone: +39 (51) 597313
CAD.LAB s.p.a., v. Ronzani 7/29, Casalecchio, Italia   Fax: +39 (51) 597120
---
[ 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. ]





Author: kanze@gabi-soft.fr (J. Kanze)
Date: 1995/11/10
Raw View
Greg McGary (gkm@magilla.cichlid.com) wrote:

|> According to sec. 4.4: Qualification conversions, paragraph 3, the
|> following is NOT a const-safe conversion:

|>  char * *  --> char const * *

|> whereas this is safe:

|>  char * *  --> char const *const *

|> Why?  I don't see how *adding* `const' an any level of a multi-level
|> pointer could lessen safety.

Consider the following:

    char const      c = 'a' ;
    char*           p ;
    char**          pp = &p ;
    char const**    ppc = pp ;      //  Supposing that this were not
                                    //      illegal
    *pp = &c ;      // Oops: where does p point
    *p = 'b' ;                      //  And what is wrong here?

This was first pointed out during the development of the C standard, and
the standard was changed to eliminate the implicit casts for all but the
first level below the top.  During the C++ standardization, it was
pointed out that this went too far, and so the slightly looser rules of
C++ were adapted.  One of the members of the standards committee
actually proved that the current rules are optimal; everything safe is
allowed, and everything dangerous (like the above) is forbidden.
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
              -- A la recherche d'une activit    dans une region francophone

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