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