Topic: Mutable without mutable specifier?
Author: boukanov@sentef2.fi.uib.no (Igor Boukanov)
Date: 1997/06/15 Raw View
I would like to know what should a conforming implementation do
with the code like,
struct A {
int i;
A* a;
A(): i(10), a(this){}
void test() const {
a->i = 11;
}
};
Here the line a.i = 10 modifies the const object.
The CD2 has the statement about this case,
9.3.2.2 In a const member function, the object for which the function is
called is accessed through a const access path; therefore, a const
member function shall not modify the object and its non-static data
members. [Example:
struct s {
int a;
int f() const;
int g() { return a++; }
int h() const { return a++; } // error
};
int s::f() const { return a; }
The a++ in the body of s::h is ill-formed because it tries to modify
(a part of) the object for which s::h() is called. This is not
allowed in a const member function because this is a pointer to const;
that is, *this has const type. ]
But how can a compiler enforce that "shall not modify the object"
in the above example?
--
Thanks in advance for your comments,
Igor Boukanov.
igor.boukanov@fi.uib.no
http://www.fi.uib.no/~boukanov/
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/06/16 Raw View
boukanov@sentef2.fi.uib.no (Igor Boukanov) writes:
>I would like to know what should a conforming implementation do
>with the code like,
>
>struct A {
> int i;
> A* a;
> A(): i(10), a(this){}
> void test() const {
> a->i = 11;
> }
>};
This code is well-formed, and should be accepted by a conforming
implementation. If you append
int main() {
A x; // non-const
x.test();
return 0;
}
the result is a strictly conforming program.
Alternatively, if you instead append
int main() {
const A x; // const
x.test();
return 0;
}
then the program is still well-formed, but it has undefined behaviour
(by 7.1.3.1/4).
>The CD2 has the statement about this case,
>
>9.3.2.2 In a const member function, the object for which the function is
> called is accessed through a const access path; therefore, a const
> member function shall not modify the object and its non-static data
> members.
What this is intended to mean is that accesses that are implicitly via
"this" are considered to be accesses through a const access path if they
occur in a const member function (and therefore, by 7.1.3.1/3, any possible
modifications via such access paths are ill-formed). The text above is not
meant to restrict modifications via other access paths.
Certainly the wording is poor and could be improved.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: anatoli@ptc.com
Date: 1997/06/16 Raw View
In article <5o1d81$l11$1@toralf.uib.no>,
boukanov@sentef2.fi.uib.no says...
>
>I would like to know what should a conforming implementation do
>with the code like,
>
>struct A {
> int i;
> A* a;
> A(): i(10), a(this){}
> void test() const {
> a->i = 11;
> }
>};
>
>Here the line a.i = 10 modifies the const object.
^^^^^^^^ a->i = 11 presumably
[rest of post elided]
Sigh. I always suspected that const correctness cannot be
ensured without const constructors. Now my worst fears seem
to come true.
It seems that there is no way to fix this problem without
breakin a huge amount of existing code and without resorting
to another "no diagnostic is required" rule.
If I'd designed C++ from the beginning, I'd introduce const
constructors. Const objects would be possible to construct
with const constructors only. The `this' pointer in a const
constructor of class T would have the type T const * const;
however, *implicit* accesses to `this' would be invisibly
augmented by const_cast. Likewise for volatile.
So the example above would look like this.
/////////////////////////////////////////////////////////////////////////
// Not a C++ code, for illustrative purposes only.
struct A {
int i;
A* a;
A(): i(10), a(this){}
#if 0 // the constructor below is now illegal
// so it's #if'd out
A() const : i(10), // ok : equivalent to
// (const_cast<A&>(*this)).i = 10
a(this){} // illegal : `this' is of type A const * const,
// `a' is of type A *.
#endif
void test() const {
a->i = 11;
}
};
A aa;
A const & ab = aa;
ab.test (); // ok : object being modified is not const, and is
// accessed through non-const path.
const A ac; // illegal : A does not have a const constructor.
/////////////////////////////////////////////////////////////////////////
Those are only dreams, of course.
Or not?
--
anatoli@ptc.com
My volatile opinions only.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: anatoli@ptc.com
Date: 1997/06/16 Raw View
In article <5o2ehh$cvm@mulga.cs.mu.OZ.AU>, fjh@mundook.cs.mu.OZ.AU says...
[example elided]
[some reasoning elided]
>>The CD2 has the statement about this case,
>>
>>9.3.2.2 In a const member function, the object for which the function is
>> called is accessed through a const access path; therefore, a const
>> member function shall not modify the object and its non-static data
>> members.
>
>What this is intended to mean is that accesses that are implicitly via
>"this" are considered to be accesses through a const access path if they
>occur in a const member function (and therefore, by 7.1.3.1/3, any possible
>modifications via such access paths are ill-formed). The text above is not
>meant to restrict modifications via other access paths.
>
>Certainly the wording is poor and could be improved.
>
The const member function is strictly irrelevant to the problem.
The real problem is that `this' pointer can be stored away in a
constructor and used to modify a const object later:
struct A * a;
struct A
{
int i;
A () : i(0) { a = this; }
};
int main ()
{
A const aa;
a->i = 1;
return 0;
}
CD2 sez:
[7.1.5.3]
<<< elided >>> [Note: cv-qualifiers are supported by
the type system so that they cannot be subverted without casting
(5.2.11).]
CD2 apparently does not say that an object declared const cannot
be modified (after its constructor exit) without casting.
I believe, however, that this is the intent. If it is not, this
should be clearly stated, to avoid confusion. If it is, the hole
should be closed, even if by another "no diagnostic is required"
[shrug] rule.
--
anatoli@ptc.com
Just my opinions, based on nothing.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: "Anatoli Tubman" <anatoli@ptc.com>
Date: 1997/06/16 Raw View
On Jun 16, 12:42, John Hickin wrote:
> Subject: Re: Mutable without mutable specifier?
> >CD2 apparently does not say that an object declared const cannot
> >be modified (after its constructor exit) without casting.
> >I believe, however, that this is the intent.
>
> I don't see how one can take this view and remain consistent with
> other parts of the language. As an example take
>
> X& X::op=( const X& other ) { ... }
>
> where the code ... inside may very well effect a modification to 'other' by
> virtue of the fact that it is the same as *this. If you tell me that I must
> code the member function to take account of potential ailiasing then I would
> counter that in the constructor of an object, especial care should be taken to
> prevent the export of the this as a non-constant pointer.
>
By "const object" or "object declared const" I (and the CD2, I presume)
mean something like
const SOMETYPE someobject;
You probably mean lvalue, not object. It is perfectly legal to modify
an object when there is a non-modifiable lvalue (read: reference to const)
that refers to that object, even through this very same lvalue
(using const_cast), *if the object itself is non-const*.
It is illegal to modify an object declared const
*even through a modifiable lvalue*.
My whole point was that even if an object is declared const,
and if there is no single cast in the program, and if there
is no other undefined behaviour in the program, and if the
object's constructor is already exited, there nevertheless
may be a modifiable lvalue that refers to the object -- namely,
the `this' pointer stored away by the constructor.
This is the only way to subvert the type system without resorting
to cast or to an undefined behaviour (for example, one may
write a const pointer to file and read it back as non-const --
but this has always been undefined).
Interestingly enough, in C this is not possible --
and C++ is presumably safer.
Hope it helps.
--
Anatoli Tubman <anatoli@ptc.com>
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/06/16 Raw View
anatoli@ptc.com writes:
>CD2 sez:
>
>[7.1.5.3]
><<< elided >>> [Note: cv-qualifiers are supported by
>the type system so that they cannot be subverted without casting
>(5.2.11).]
Yes, that is a lie.
(It is in a "Note", though, and notes are not normative, so
at least it is a non-normative lie.)
>CD2 apparently does not say that an object declared const cannot
>be modified (after its constructor exit) without casting.
>... the hole should be closed, even if by another "no diagnostic is required"
>[shrug] rule.
No, CD2 does say that. The "no diagnostic is required" rule that you're
looking for is in 7.1.5.1[dcl.type.cv]/4 and 3.8[basic.life]/9.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: Pete Becker <petebecker@acm.org>
Date: 1997/06/16 Raw View
Fergus Henderson wrote:
>
> anatoli@ptc.com writes:
>
> >CD2 sez:
> >
> >[7.1.5.3]
> ><<< elided >>> [Note: cv-qualifiers are supported by
> >the type system so that they cannot be subverted without casting
> >(5.2.11).]
>
> Yes, that is a lie.
>
Well, perhaps an overstatement, perhaps even an incorrect one. But a
"lie"? Really? Who's behind this deliberate deception, and what are they
trying to gain from it?
(Sorry, but I've always found this usage of "lie" to be extremely
misleading, and an impediment to serious discussions).
-- Pete
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: anatoli@ptc.com
Date: 1997/06/17 Raw View
In article <5o3ecq$4kh@mulga.cs.mu.OZ.AU>, fjh@mundook.cs.mu.OZ.AU says...
>
>anatoli@ptc.com writes:
>
>>CD2 sez:
>>
>>[7.1.5.3]
>><<< elided >>> [Note: cv-qualifiers are supported by
>>the type system so that they cannot be subverted without casting
>>(5.2.11).]
>
>Yes, that is a lie.
>
>(It is in a "Note", though, and notes are not normative, so
>at least it is a non-normative lie.)
>
>>CD2 apparently does not say that an object declared const cannot
>>be modified (after its constructor exit) without casting.
>>... the hole should be closed, even if by another "no diagnostic is required"
>>[shrug] rule.
>
>No, CD2 does say that. The "no diagnostic is required" rule that you're
>looking for is in 7.1.5.1[dcl.type.cv]/4 and 3.8[basic.life]/9.
CD2 says only that any attempt to modify an object declared const
results in undefined behavior. It does not specify exactly how
such attempts may be coded. It does provide examples, and all of
them use a cast.
Many readers may have an impression that cast is the only way
to modify a const object in a program that otherwise has no
undefined behavior. This is true for ANSI C, but apparently
not for C++. Therefore, ANSI C is more typesafe than C++.
Worse yet, this (hopefully) single hole in the type system
is not clearly identified as such. One might think that the
hole is small and altogether unimportant, but it's nevertheless
a hole.
I don't believe that this is exactly what the committee intended.
The note in 7.1.5.3 makes me think so. Notes, non-normative
as they are, were designed to clarify intents and/or beliefs of the
committee with respect to the language, not for entertainment of
the public.
My cocnlusion: the hole must be either (1) fixed or (2) clearly
marked with red flags, blinking lights, and 48pt black-on-yellow
bold italic underlined outlined boxed (insert your own attribute here)
[just kidding] description.
Guess what I'd prefer. Committee members, anybody?
--
anatoli@ptc.com
const Opinions my_opinions; // what const is doing here?
---
[ 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 ]
[ FAQ: http://reality.sgi.com/employees/austern_mti/std-c++/faq.html ]
[ Policy: http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu ]
Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/06/17 Raw View
Pete Becker <petebecker@acm.org> writes:
>Fergus Henderson wrote:
>>
>> anatoli@ptc.com writes:
>>
>> >CD2 sez:
>> >
>> >[7.1.5.3]
>> ><<< elided >>> [Note: cv-qualifiers are supported by
>> >the type system so that they cannot be subverted without casting
>> >(5.2.11).]
>>
>> Yes, that is a lie.
>
> Well, perhaps an overstatement, perhaps even an incorrect one. But a
>"lie"? Really? Who's behind this deliberate deception, and what are they
>trying to gain from it?
> (Sorry, but I've always found this usage of "lie" to be extremely
>misleading, and an impediment to serious discussions).
You're right, that was a poor choice of words. For the record,
I just meant "falsehood", not "deliberate falsehood", and I was
not attempting to malign or impugn anybody. If anyone was offended,
I apologize.
--
Fergus Henderson <fjh@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3 | -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated. To submit articles: Try just posting with your
newsreader. If that fails, use mailto:std-c++@ncar.ucar.edu
comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
Comments? mailto:std-c++-request@ncar.ucar.edu
]