Topic: What const is/was for (was: delete of const objects o.k.?)


Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/10/09
Raw View
Nathan Myers wrote:
>
> Christopher Eltschka  <celtschk@physik.tu-muenchen.de> wrote:
> >Nathan Myers wrote:
....
> >> There are many contexts where a reference would be useless.
> >
> >If you really need a pointer, you still can apply the address-of
> >operator on the return type. ...
>
> There are many contexts where a reference would be useless.

You're repeating yourself. You can't expect someone who's already read
those words and didn't believe them, to be convinced just because you
chose to repeat them. Can you give an example? The main difference
between references and pointers is syntax, not semantics, so I'd expect
that any example you give could be rewritten to use a reference instead.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/08
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

[...]

| These appear parallel, but in use they differ fundamentally, because
| the "delete pointer" can appear anywhere a copy of the pointer exists.

Did I say otherwise? Notice that I did *not* put braces around the
new/delete-expression. On purpose.

| It might be in the same block (as in the example that sought to draw
| a parallel) or it might be in some other library entirely.
|
| It is this very real difference that makes the argument:
|
|   { T  const t; }
|   { T const* p = new T; delete p; }
|
| fundamentally weak: it tries to draw a parallel by specifically
| excluding the real-world usage pattern of dynamic objects, which
| is relentlessly non-lexical.

Well, you transmuted my example.  So anything you can say thereafter
can't apply.
[...]

| Deletion of pointers is in fact very common in user code.
| Deletion of the wrong pointer is correspondingly easy.

Deletion of pointers may be common in user code.  But does it mean it
is safe?  No, IMHO.


--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <jerrold.leichter@smarts.com>
Date: 1999/10/08
Raw View
| > If it makes you feel happier, imagine that:
| >
| >         {       const T r;
| >                 ...
| >         }
| >
| > is actually implemented as:
| >
| >         {       T r';
| >                 const T r& = r';
| >                 ...
| >         }
| >
| > where r' is a compiler-generated name....
| >
| > *There is no guarantee that const objects won't change.*  The only
| > guarantee that const has *ever* attempted to provide is that a
| > const-qualified access path cannot be used to change the object.
|
| While the text above describes a proposed alternative to the current
| definition of const, it does not describe what the standard currently
| dictates.
|
| Currently, const is given meaning primarily by paragraph 4 of
| 7.1.5.1 [dcl.type.cv]:
|
|      Except that any class member declared mutable (7.1.1) can be
|      modified, any attempt to modify a const object during its
|      lifetime (3.8) results in undefined behavior.

One of the things that make this discussion so confusing is the constant
jumping back and forth between const objects and pointers to const (or
const ref's).  I see I crossed that line again.  What you say is true.
I have in the past explained why the compiler could delete a const
object by imagining that it const_cast the pointer at the close bracket.
(That the result is "undefined" for a user program is irrelevant to the
compiler, which can make it mean whatever it wants for itself.)

This way seemed cleaner, but as you point out is just a bit different.

| The guarantee that const provides is that no program may rely on
| changing the object.  A compiler can take advantage of this guarantee
| to perform optimizations; it may not make such optimizations in
| the second snippet above.

Actually, if it's optimizations you're concerned with, the practical
difference is nil.  Most compilers *implement* pointers and int's using
the same underlying object; but that doesn't mean you can treat them as
equivalent - they differ in type.  Even if the compiler "implemented" a
const as I suggest, the rules of 7.1.5.1 still apply.  The result of
modifying an object that, in the original C++, was declared as const is
undefined just as the result of reinterpret_cast'ing an arbitrary int to
a pointer gives an undefined result.

| I've pointed out that a loophole in 3.8 [basic.life], while not
| weakening this guarantee, can make it difficult for a compiler to
| make these optimizations when the const object is dynamically
| allocated.

Actually, it makes the guarantee useless for dynamic objects.  No
optimization that assumes anything about an object can survive its
deletion.  That the object's lifetime has ended doesn't help unless
the compiler can tell that this has happened - i.e., consider:

 void f(const T* t);

 { const T* t = new const T(1); // (1) initializes t.x

  f(&t);
  ... t.x ...

The compiler would have to have some way to check whether t's lifetime
had ended before it could safely use t.x - T's destructor could have
done anything it liked to t.x.  No implementation I've ever heard of
keeps the necessary information around, and the cost is such that it's
unlikely to be worth it.

| But rather than taking this to be a fatal flaw in the idea of dynamic
| const objects, I'd just like to see the loophole closed.

Which loophole?  There is the specific loophole that t could be alive,
but with a different value for x, as a result of executing a placement
new over t, beginning a new lifetime.  That, you can close by extending
the current text that makes placement new over the memory previously
occupied by a static or auto const produce undefined results.  But be
careful:  The effect of that is to make explicitly calling the
destructor on a dynamic const object effectively useless.  As I pointed
out in another message, once you've explicitly destructed an auto or
static const object, you cannot exit the block/program without entering
"undefined behavior" territory:  At block/program exit, the object must
be alive - since it will be destructed; and yet you cannot use placement
new on it, so you can't *make* it alive.  For dynamic objects, if you
close the loophole, once you applied the destructor, the only thing you
could do with the resulting raw memory is abandon it!

However, for optimizations there's just as much of a loophole the case
that the object is just plain deleted, and the only way to close *that*
is to forbid deletion through const pointers.
       -- Jerry
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/08
Raw View
Alexandre Oliva  <oliva@lsd.ic.unicamp.br> wrote:
>On Oct  5, 1999, ncm@nospam.cantrip.org (Nathan Myers) wrote:
>
>template <typename T> T *make_new() { return new T; }
>template <typename T> void delete_it(T *t) { delete t; }
>template <typename T> void do_something(T &t, ...) {
>  T *another_t = make_new<T>();
>  /* do something with t and *another_t */
>  delete_it(another_t);
>}
>
>Now add to the Standard the rule that `delete t' is invalid if T is a
>pointer to a constant object.  The templates are suddenly rendered
>useless for any const T, because delete_it would be ill-formed.  And
>you'd need some traits helper template class with specializations for
>`const' types to be able to remove the const from T, in order to make
>the delete conforming.

Senhor Oliva, are you forgetting that we are talking about what _was_
the status quo?  Of course changing the definition of const back now
would break code, just as changing it before broke interfaces.

Most significant templates cannot be instantated on "const T" unless
they were carefully coded with that in mind.  In practice very few are.
(Have you ever seen such a practice mentioned in a textbook?)  Most
such templates need to perform assignment somewhere, and would need
either to cast away const, or to play destroy/reconstruct games.

>But then, if it becomes documented that it is possible to delete a
>pointer to const by simply applying a const_cast to it, people might
>just get used to doing it, and see it as a weirdness of C++.  So why
>introduce it anyway?

It _was_ so documented.  There is no question of "introducing it" --
it was very much there already.  Still, casts did and still attract
appropriate attention.

>For safety, you say.  But pointers aren't safe.  It has always been
>well-formed, albeit unsafe and undefined, to write `T t; delete &t;',
>so I don't buy the safety argument.  Any safety you could derive from
>such a rule it would be merely illusory,

This is the "const isn't useful anyway" argument.  It's a slippery
one, because where do you stop?  Why enforce constness restrictions
at all?  "They can't detect all errors anyhow."

To make the "const wasn't useful anyway" argument stick, you need to
show how the restriction on deletion of pointers-to-const was markedly
_less_ useful than all the other restrictions on operations on const
objects, or on pointer-to-const.  So far nobody has essayed that,
probably for good reason.

>... and it would certainly break
>existing code, so I don't see the point of pursuing this issue any
>further.

Nobody is talking about changing const back.  The discussion is
about the several logically-invalid arguments presented (mainly)
in favor of the change, both before and after the change was made --
and why they were (and still are!) so popular.

The "const wasn't useful anyway" argument was invalid only in that
nobody who tried it bothered to demonstrate why const should be
thought less useful for deletion than for any other operation on
pointers-to -const, and nobody suggested eliminating all restrictions
on operations via pointer-to-const.

There were plenty of more-egregious violations of logic that might
be easier to discuss.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/10/08
Raw View
Nathan Myers wrote:
>
> Christopher Eltschka  <celtschk@physik.tu-muenchen.de> wrote:
> >Nathan Myers wrote:
> >> A key use for "old const" was in cases much like:
> >>
> >>   T const* f() { static T t; return &t; }
> >
> >This should have been coded as
> >
> >  T const& f() { static T t; return t; }
> >
> >This way it's clear for everyone that the return value should
> >not be deleted (you don't call delete on pointers obtained
> >through the address-of operator, do you?)
>
> There are many contexts where a reference would be useless.

If you really need a pointer, you still can apply the address-of
operator on the return type. That way it's obvious in _user_ code
that this pointer is not safe to delete.
And users which don't need a pointer can avoid the extra
dereferencing.

>
> >> The point of const here is not to indicate who should delete it,
> >> it is to indicate that the client should *never* delete it, and
> >> further, if it's deleted accidentally (or assigned through) the
> >> compiler should forbid it.
> >
> >I hope the intent was to indicate that the user should not
> >_modify_ it. Otherwise the interface is broken, since the
> >operation "f()->modify();" is disallowed when it shouldn't be.
>
> The intent was that nobody would do anything to it.  (Of course
> the new definition of const breaks that intent.)  Terms like
> "modify" are controversial in the context of this discussion, and
> thus not very meaningful.

Everyone here agrees that changing the state of the object
is a modification of the object, and that const is used to
prevent that. The only disagreement is about if it includes
destroying the object. It's obvious that in this example,
the object should not be destroyed. Therefore my use of
"modifying" is not at all ambiguous. And I bet everyone
has understood that "modify()" is assumed to be a non-const
member function of T.

BTW, you _now_ have changed the documented intent (and exactly
in that way I suggested - well, litterally you changed it
even more, but I'm not going to nit-pick on that).
Previously you said that the "const" was there to prevent
users deleting the object. My objection was that you did
more than intended: You also prevented any call to non-const
member functions (or assignment to non-const public members).
Now you changed the documented intent, so that exactly this
is not intended.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/08
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>
>| These appear parallel, but in use they differ fundamentally, because
>| the "delete pointer" can appear anywhere a copy of the pointer exists.
>...
>| It might be in the same block (as in the example that sought to draw
>| a parallel) or it might be in some other library entirely.
>|
>| It is this very real difference that makes the argument:
>|
>|   { T  const t; }
>|   { T const* p = new T; delete p; }
>|
>| fundamentally weak: it tries to draw a parallel by specifically
>| excluding the real-world usage pattern of dynamic objects, which
>| is relentlessly non-lexical.
>
>Well, you transmuted my example.  So anything you can say thereafter
>can't apply.

The example above is the one that was presented in full committee,
prior to the vote that changed const semantics applied to deletion,
and frequently since.  This thread is specifically for discussion of
those invalid arguments.

I'm glad to see that you agree it was not a sound argument.

Any sound arguments you may have in favor of or against the change,
while interesting, may be a bit off-topic.

>| Deletion of pointers is in fact very common in user code.
>| Deletion of the wrong pointer is correspondingly easy.
>
>Deletion of pointers may be common in user code.  But does it mean it
>is safe?  No, IMHO.

Of course deletion of pointers is unsafe.  It is specifically that
unsafety that makes (made?) it appropriate for the language to help
enforce restrictions.  You have just constructed a good argument
against the change.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/10/08
Raw View
Nathan Myers wrote:
>
> Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
...
> >Well, you transmuted my example.  So anything you can say thereafter
> >can't apply.
>
> The example above is the one that was presented in full committee,
> prior to the vote that changed const semantics applied to deletion,
> and frequently since.  This thread is specifically for discussion of
> those invalid arguments.

You may want that to define this thread as being about that argument,
but the decision isn't yours to make. Gabriel made a different argument,
and has a reasonable expectation that any response to Gabriel's argument
would actually pay attention to the differences between Gabriel's
argument and the one you want to discuss.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/08
Raw View
Christopher Eltschka  <celtschk@physik.tu-muenchen.de> wrote:
>Nathan Myers wrote:
>> Christopher Eltschka  <celtschk@physik.tu-muenchen.de> wrote:
>> >Nathan Myers wrote:
>> >> A key use for "old const" was in cases much like:
>> >>
>> >>   T const* f() { static T t; return &t; }
>> >
>> >This should have been coded as
>> >
>> >  T const& f() { static T t; return t; }
>> >
>> >This way it's clear for everyone that the return value should
>> >not be deleted (you don't call delete on pointers obtained
>> >through the address-of operator, do you?)
>>
>> There are many contexts where a reference would be useless.
>
>If you really need a pointer, you still can apply the address-of
>operator on the return type. ...

There are many contexts where a reference would be useless.
We're talking about real programs here, not academic exercises.

>> >> The point of const here is not to indicate who should delete it,
>> >> it is to indicate that the client should *never* delete it, and
>> >> further, if it's deleted accidentally (or assigned through) the
>> >> compiler should forbid it.
>> >
>> >I hope the intent was to indicate that the user should not
>> >_modify_ it. Otherwise the interface is broken, since the
>> >operation "f()->modify();" is disallowed when it shouldn't be.
>>
>> The intent was that nobody would do anything to it.  (Of course
>> the new definition of const breaks that intent.)
>
>BTW, you _now_ have changed the documented intent ...
>Previously you said that the "const" was there to prevent
>users deleting the object. My objection was that you did
>more than intended: You also prevented any call to non-const
>member functions (or assignment to non-const public members).
>Now you changed the documented intent, so that exactly this
>is not intended.

Const had a documented meaning.  Interfaces used that documented
meaning.  To call attention to one aspect or other of that meaning
is not "changing intent".

Const was once useful to prevent violation of interface invariants,
by disallowing (without a cast) all operations which could possibly
violate any invariant.  Now it is useless for that purpose.  Many
interfaces were designed depending on that quality of const; now
_all_ such interfaces are broken.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/10/05
Raw View
Nathan Myers wrote:

> I'm happy to say that const was "changed" and get back on-topic:
> -- the repeated posting of a small group of logically-unsound
> arguments in favor of the change, to the (near-?) exclusion
> of the logically-sound ones.

Why don't you also consider the logically-unsound ones
against the change ? Have you missed them ?

--

Valentin Bonnard
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>
>| >If constness doesn't imply undestructibility, why should one have to
>| >go through administratives before ending a newed object's lifetime
>| >whereas in the auto case, one just has to leave the scope?
>|
>| Because we're talking about the delete-expression, which does
>| not apply to auto objects.  You don't have any choice about the lifetime
>| of auto objects: it is purely lexical, and the compiler takes care of
>| running the destructor.
>
>Using delete-expression is the way one goes in order to destroy
>an object and to release associated memory.  The compiler takes care
>or running the destructor.  The main difference is the control of the
>object lifetime, and this is entirely under the programmer's control.
>Thus my initial query: why should he have to go round an assault
>course before destroying the object (and releasing the occupied
>memory)?
>Notice that I'm seeing the destruction as the *desired* effect of
>deletion.

Right.  The reason behind the distinction is the fundamental difference:
there is no possibility of error when destroying an auto object, because
its lifetime is purely lexical, and entirely understood at compile time.
The compiler creates it, the compiler destroys it, and you get to use it
in between.  If the compiler were obliged to insert a const_cast, you
wouldn't see it, just as you don't see the destructor call.

(Somebody who is used to LISP might ask why we have to "go round
an assault course" deleting dynamic objects at all: why not just
zero the pointer, and let the garbage collector do the work?
Dynamic objects are a lot more like auto objects in LISP than
they are in C++.)

Because of these fundamental differences -- lexical vs. user-managed
object lifetime, and implicit vs. explicit lifetime management --
a simple equation of auto and dynamic objects doesn't hold up,
and anyway isn't sufficient to justify what amounts to quite a
substantial change to the language.

You really do need to reference something outside the rules themselves,
and that's what makes the simple analogy to auto objects weak.

>| ...   As Andrew is at pains to repeat
>| frequently, it is a judgment call.  Such a judgment should be (and should
>| have been!) made based on analysis of the effect on real programs and
>| programmers, not on sterile arguments that have been proposed to settle
>| the argument without any real-world analysis.
>|
>| That the purely-abstract arguments advanced in this case have all betrayed
>| fundamental confusions is extremely interesting.  Since the language will
>| not be changed, any issue of what decision the committee should have made
>| is moot, but the enormous holes in the arguments presented remain worthy
>| of study.
>
>Before stating there are confusions, perhaps would you want to make sure
>there are *really* confusions, not just divergence from your point of
>view, nor analysis of the opponents' point of view.
>
>I'm not trying to convince people that the change was right or wrong.
>
>I'm trying to analyze your opponent's arguments instead of
>peremptorily ordering that their arguments are logically unsound, or
>purely-abstract.

I never peremptorily ordered that their arguments were logically unsound
(though I've been accused of that); I pointed out specific holes in the
arguments.  I appreciate your willingness to actually discuss the problem.
I still believe that incareful use of "deletion" and "destruction" has
confused at least some people by eliminating in discourse a very real
difference in reality.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Valentin Bonnard  <Bonnard.V@wanadoo.fr> wrote:
>Nathan Myers wrote:
>
>> I'm happy to say that const was "changed" and get back on-topic:
>> -- the repeated posting of a small group of logically-unsound
>> arguments in favor of the change, to the (near-?) exclusion
>> of the logically-sound ones.
>
>Why don't you also consider the logically-unsound ones
>against the change ? Have you missed them ?

I pointed one out, but it wasn't repeated.  If you know of one that
has been posted repeatedly, by all means point it out.  Logically
unsound arguments are possible in favor of any position, but are
unwelcome in most quarters -- with peculiar exceptions.

As always, it is the exceptions that are interesting.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
><ncm@nospam.cantrip.org> writes
>
>>Such a judgment should be (and should have been) made based on analysis
>>of the effect on real programs and programmers,
>
>And what makes you think it wasn't?  You have absolutely no idea what
>caused individuals to vote one way or another.

I know what arguments were presented in committee session.  No such
analysis was presented, and no time was allowed for those of us who
would have preferred the opportunity to perform it.

Francis, you said yourself that you were influenced by (what has turned
out to be a fundamentally misleading) analogy with the Unix file system.

Others have reported similarly.  Therefore, I _do_ have some idea what
caused (some) individuals to vote one way or other, and it's deeply
disturbing -- and interesting.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
> Nathan Myers <ncm@nospam.cantrip.org> writes
>>Are Francis's remarks above the best we can do?
>>Can anybody please actually take on defending the argument?
>
>You ask for logical arguments defending a judgement call.  I do not
>think such can exist or there would not be a judgement call to make.

Francis, this is at least the third time you have posted
confusing the two issues:

 - whether the committee chose correctly, and
 - arguments used in support or apology for the change.

The two are independent, and I have been very careful not to mix
them up.  We each have opinions about the former, but the latter
are (or should be!) subject to objective analysis.

>You stated that you were puzzled by the decision of the Standards
>Committees to change the rule because you found the reasons
>unconvincing.

No, Francis, I did not state any such thing.  As I have said in response
to each of your previous false and unfounded assertions, I am not at all
puzzled by the committee's decision.

>IOWs you would have made a different call.  Fine, you are
>entitled to that opinion, but each and every Committee member is also
>entitled to their call.  Judgement calls are often based on experience.

The judgment call -- the committee's decision -- is not at issue here.

>You have claimed, IIRC, that the Committee acted illogically in making
>the change, or were swayed by illogical arguments.

No, I did not claim any such thing.  Illogical arguments were presented,
both before the decision (in support of the change), and after (in
apology).  It is those illogical arguments that are at issue.  Any
swaying, swinging, shimmying, quaking, or other undulations of the
committee are not subject to argument, and are not the topic here.

>I maintain that the
>onus is on you to demonstrate that they were swayed by illogical
>arguments.  I simply do not think you can do that.

It is not possible to demonstrate how they were swayed.  It _is_
possible to demonstrate that the arguments actually presented were
and remain illogical.  I have done so.  Your assertions about my
motivations are neither welcome nor appropriate.

>You are entitled to
>believe they were but equally I am entitled to believe they were not.
>I do not need to defend any argument because my position is that you
>cannot arrive at a judgement call by exercising logic.

Francis, I never asked you defend a judgment call.  I asked if you
could defend the arguments.  Despite your repeated assertions to
the contrary, I have been consistent in treating the arguments and
not the opinions they claim to support.  I wish you would be as
careful.

If you're not willing to defend the arguments, then don't criticize me
for asking if somebody else will -- or why nobody else can.  Your remarks
can only distract others from the topic where progress is still possible.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/05
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

| Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
| >
| > Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes
| >>Now, if you do "delete p;", you are changing the behaviour of
| >>all pointers/references to the object, and therfore according
| >>to the definition above, the object should be considered to
| >>be changed. Therefore it should be forbidden for pointer to
| >>const.
| >
| >But that argument could just as well apply to a const auto object once I
| >have stored its address in a pointer from a wider or different scope.
|
| Nobody has any choice about when an auto object goes out of scope,
| and its lifetime ends.

I disagree.  If I define an object in a particular scope it is
because I deliberately choose to tie its lifetime to its scope.
Otherwise I would have used an object on heap.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
><ncm@nospam.cantrip.org> writes
>>Deletion is not the same as destruction.  Every object gets
>>destroyed, but only free-store objects get deleted first.
>
>I almost agree with everything apart from the last word.  Freestore
>objects can be destroyed via either calling delete (and their
>destruction is then part of that, the first part to be precise) or
>by an explicit call to the destructor.

It was always possible to destroy any object by an explicit call to
the destructor.  Nobody proposed changing that.

>It is the second of those options that
>punches a gaping hole through the concept of const.

Some people have suggested it would have been more consistent to
forbid an explicit destructor call on a const object.

In practice, anybody doing that sort of thing is operating outside the
type system anyway, and probably would not benefit from or welcome
type-system restrictions.  Furthermore, fixing it would have broken
code, so nobody proposed it.

>We can explicitly
>call the dtor on an object and then use placement new to construct a
>similar but not necessarily identical (in the sense of having an
>identical state) object in its place.  According to my (perhaps
>erroneous) understanding this process is well formed according to the
>Standard.  It is also even harder to detect [such] code than simple uses
>of delete.

Explicit destructor calls are easy to spot.  Anyhow, nobody inserts
explicit destructor calls by accident, and any place they appear
attracts intense scrutiny.

>The first option I referred to above is not something that happens
>before destruction, destruction is a necessary part of any use of
>delete.

You can execute a delete-expression, or you can call the destructor.
They are different expressions, and they can and do have different
semantics.  The change under discussion affected only delete-expressions,
so anything else is a distraction.

>From my perspective, once you can explicitly destroy a const
>object the genie is out of the bottle and the rest is just playing word
>games to provide some illusion of extra safety.

Are you justifying a new language defect by reference to an old one?
That's a slippery slope.

>The problem with
>illusions is that they get in the way of learning (not to try to delete
>things you do not own, because the compiler will look after you).

This is Andrew's "const wasn't useful anyway" argument again, which
was not one of those that was inherently illogical -- just "wrong IMHO".

Anyway, since you asked... the point of the compiler issuing an error
message on known-improper deletions is not to "look after me", it's to
protect my library against its clients' mistakes, and my library's
clients against their own.  Protecting against common errors is
considered an honorable role for the compiler, in other contexts.

Since nobody accidentally calls explicit destructors, the protection
was in practice not illusory, but truly helpful.

Anyhow... all this is moot, because the change happened.  Treating
the above as a not-clearly-illogical argument, we remain no closer
to understanding why clearly illogical arguments have been (and are
being!) advanced in support of the change, and nor why they avoided
scrutiny by those whose job it was to scrutinize proposed changes.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jens Kilian <Jens_Kilian@bbn.hp.com>
Date: 1999/10/05
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:
> But no such example can exist because we could always have used
> const_cast to do the delete anyway.

You can grep for a const_cast.

--
mailto:jjk@acm.org                 phone:+49-7031-14-7698 (HP TELNET 778-7698)
  http://www.bawue.de/~jjk/          fax:+49-7031-14-7351
PGP:       06 04 1C 35 7B DC 1F 26 As the air to a bird, or the sea to a fish,
0x555DA8B5 BB A2 F0 66 77 75 E1 08 so is contempt to the contemptible. [Blake]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Valentin Bonnard  <Bonnard.V@wanadoo.fr> wrote:
>Nathan Myers wrote:
>
>> The most interesting is the one that claims that a pointer-to-const
>> is OK to delete because afterward the object doesn't exist, so wasn't
>> really const anyway.

> ???

Valentin, this is what was actually posted:

  Logically speaking, at the "delete ptr", the object pointed to by
  'ptr' no longer exists and so it matters not whether the object is
  const or not.

I did not make it up.

>> I hardly know how to discuss that in measured
>> terms.  It's a howler, and it keeps getting posted.
>
>Nonsense.  A pointer to const is really const over the
>_lifetime_ of the pointed to object. When you end the
>lifetime of the object, const stops making sense.

Valentin, you keep saying that.  It's obvious, and always was.
It doesn't help decide anything.

The issue voted on (remember, there really was a vote!) was _whether_
_to_allow_ the lifetime to be ended without a const_cast.  Do I need
to repeat that again?  It seems to me a very simple statement.

You cannot talk about "after the lifetime is ended" without assuming
that is has ended, and thus has been _allowed_ to be ended.  That is,
you cannot talk about it without assuming the conclusion you claim
to be arguing for.  You cannot support a conclusion by assuming the
conclusion.  This is very, very basic logic.


>Passing a const pointer to a function guaranties that it
>won't try to modify the object w/o a cast over its lifetime
>through this pointer (of course, it could through another
>non const pointer pointing to te same object).

Yes, that was always what const did.

>Passing a pointer to const currently does _not_ guarantee
>that the called function won't end the lifetime of the
>object, making all other pointers/references to the
>object unusables.

Yes, that is how it was changed.  So?

>Nathan, you can understand that. I have already given you
>two definitions of const, so that you could tell the one
>you prefer.

Those are not two definitions.  Those are both the status quo.

> If you choose the ``referee remains valid''
>definition, then you won't accept the argument presented
>in this message. Still, I am sure you can _understand_ it.

There is nothing to choose.  You made some obviously true
statements that had nothing to do with the argument you
say you are explaining.  You made some other statements
that were equivalent to the fallacious argument, as I
demonstrated.  What was your point?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/05
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

[...]

| Explicit destructor calls are easy to spot.  Anyhow, nobody inserts
| explicit destructor calls by accident, and any place they appear
| attracts intense scrutiny.

Are you suggesting a delete-expression can be inserted by accident?
How so? Deletion is a perilous operation and everybody thinks about it
more than once before doing it.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/10/05
Raw View

Nathan Myers wrote in message <37f92b54$0$204@nntp1.ba.best.com>...
>
>Al Stevens <alstevens@midifitz.com> wrote:
>>Nathan Myers wrote
>>
>>>The most interesting is the one that claims that a pointer-to-const
>>>is OK to delete because afterward the object doesn't exist, so wasn't
>>>really const anyway.  I hardly know how to discuss that in measured
>>>terms.  It's a howler, and it keeps getting posted.
>>
>>Only because the argument that it is "logically invalid" keeps getting
>>posted.
>>
>>I think the essence of the argument that gives you howls is that
>>inasmuch as the language permits you to use new to assign an address to a
>>pointer-to-const it must also allow you to delete through that pointer to
>>avoid memory leaks.
>
>No, that's not the argument.  You just described the status quo both
>before and after the change.

Please don't snip out of context to make the quote fit how you wish to
respond. Complete the quote, and you'll see that I acknowledged that.

>The essence of the argument is (as stated
>by Siemel):
>
>> > ... at the "delete ptr", the object pointed to by
>> > 'ptr' no longer exists and so it matters not whether the object is
>> > const or not.


I don't know whether Siemel identified that as its essence (message scrolled
off my reader) or you assumed that, but I disagree.This is an aspect of the
argument that gives you pause, but is only part of it and not what motivates
it, in my opinion. This part of the argument is not illogical at all (to me)
despite your assertions to the contrary, and I happen to agree with the
association of delete and destruction, despite many arguments here that want
to somehow disassociate them. None of those arguments have persuaded me to
change that opinion. The argument that you quoted, however, is just not
compelling enough to justify the change, which has broader consequences,
which is why the argument doesn't work for me.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/10/05
Raw View
Francis Glassborow wrote:
>
> In article <37F869ED.5509FAD2@physik.tu-muenchen.de>, Christopher
> Eltschka <celtschk@physik.tu-muenchen.de> writes
> >Now, if you do "delete p;", you are changing the behaviour of
> >all pointers/references to the object, and therfore according
> >to the definition above, the object should be considered to
> >be changed. Therefore it should be forbidden for pointer to
> >const.
>
> But that argument could just as well apply to a const auto object once I
> have stored its address in a pointer from a wider or different scope.

If you see the variable as reference to an unnamed object
(as I've done in the text you answered to), you can easily
imagine that the real object is not const, but only the
reference to it is const. Now you surely want to protest,
since const objects are different in that modifying them
through const_cast is undefined. However, I consider the
fact that modifying an non-const object through a pointer
to non-const obtained by casting a pointer to const is
_not_ undefined an unfortunate historic accident, due to
the fact that before mutable was invented, it's effect was
simulated using const_cast, and for compatibility it
just had to stay that way. (I don't really know if there
was any other reason to make it defined, but I can't
imagine one - the other major use of const_cast I know
is to work around bad interfaces with missing const - but
then the value is not changed anyway).

BTW, I consider taking the address of an object as something
to generally avoid (although it's not as bad as a cast).
Without taking the address, it's much harder (although not
impossible) to make a reference to a local object to
survive the object (except for the obvious case of returning
it per reference - but that shouldn't happen anyway).

[...]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/05
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

[...]

| Because of these fundamental differences -- lexical vs. user-managed
| object lifetime, and implicit vs. explicit lifetime management --
| a simple equation of auto and dynamic objects doesn't hold up,

Indeed, one cannot equate 'auto objetcs' to 'dynamic objects'; but it
does mean sense to make a parallel and to see how their lifetimes are
managed.

To create an auto (non-const) object of type T, one just needs a
definition along the lines:

 { // enter scope

    T an_auto;

to destroy it, it suffices to leave the scope

 } // leave scope

The same scheme holds for an auto const T creation/destruction.

Now, let's see the administrative machinery for a dynamic object
management.  I will consider only new-expression/delete-expression.

In order to create a dynamic (non-const) object of type T and remember
its address, it suffices to say

 T* pointer = new T; // or the appropriate form of T(...)

To destroy *pointer (and to release occupied memory), a statement

 delete pointer;

suffices.  These steps are the "common" ways to go to manage dynamic
objects liftime.

Now what if we want to manage a dynamic const object?  The Standard
says the same scheme holds, e.g.

 T const* pointer = new const T;

 // ...

 delete pointer;

Thus no additional special rule.  The ARM said one needs an extra step
in deletion: a cast is necessary.  Why?

An argument was advanced that delete-expression is going to change
`*pointer'.  Maybe.  But the important point that argument misses is
this:  it is true that the programmer made a /promise/ not to change
`*pointer' directly through `pointer' during _`*pointer' lifetime_;
but using delete-expression is the programmer's way to express that
`*pointer' lifetime is over and occupied memroy should be released.
What happens during delete-expression execution should not be and is
not part of `*pointer' lifetime.

Another argument was advanced that deletion of a pointer-to-const
might be an accident that the compiler should prevent.  But
deletion (of pointer-to-const or not) *is* a _perilous_ exercise that
every programmer pays attention to and needs to be disciplined with.
Thus it *cannot* happen accidently.

That is why I second Francis' proposal to teach users not to
manipulates raw pointers directly: deletion is too perilous, even with
ARM rules.

| and anyway isn't sufficient to justify what amounts to quite a
| substantial change to the language.
|
| You really do need to reference something outside the rules themselves,

We agree to say it was a judgment call.

| and that's what makes the simple analogy to auto objects weak.

If you agree that it was a judgment call, then certainly that decision
couldn't be drawn mechanically from 'strong' logical rules.

[...]

| >I'm trying to analyze your opponent's arguments instead of
| >peremptorily ordering that their arguments are logically unsound, or
| >purely-abstract.
|
| I never peremptorily ordered that their arguments were logically unsound
| (though I've been accused of that); I pointed out specific holes in the
| arguments.  I appreciate your willingness to actually discuss the problem.
| I still believe that incareful use of "deletion" and "destruction" has
| confused at least some people by eliminating in discourse a very real
| difference in reality.

Perhaps I didn't make my assumptions clear.  For me, deletion is the
common way to express a dynamic object destruction, and I thought it
wasn't necessary to mention that.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>| Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>| > Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes
>| >>Now, if you do "delete p;", you are changing the behaviour of
>| >>all pointers/references to the object, and therfore according
>| >>to the definition above, the object should be considered to
>| >>be changed. Therefore it should be forbidden for pointer to
>| >>const.
>| >
>| >But that argument could just as well apply to a const auto object once I
>| >have stored its address in a pointer from a wider or different scope.
>|
>| Nobody has any choice about when an auto object goes out of scope,
>| and its lifetime ends.
>
>I disagree.  If I define an object in a particular scope it is
>because I deliberately choose to tie its lifetime to its scope.
>Otherwise I would have used an object on heap.

Precisely: you chose to hand over control of the lifetime of your
auto to the compiler, which is then responsible for all the details,
and few errors are possible.  The subject here is dynamic objects,
where you have not handed over responsibility, and possible errors
are legion.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/07
Raw View
Christopher Eltschka  <celtschk@physik.tu-muenchen.de> wrote:
>Nathan Myers wrote:
>> A key use for "old const" was in cases much like:
>>
>>   T const* f() { static T t; return &t; }
>
>This should have been coded as
>
>  T const& f() { static T t; return t; }
>
>This way it's clear for everyone that the return value should
>not be deleted (you don't call delete on pointers obtained
>through the address-of operator, do you?)

There are many contexts where a reference would be useless.

>> The point of const here is not to indicate who should delete it,
>> it is to indicate that the client should *never* delete it, and
>> further, if it's deleted accidentally (or assigned through) the
>> compiler should forbid it.
>
>I hope the intent was to indicate that the user should not
>_modify_ it. Otherwise the interface is broken, since the
>operation "f()->modify();" is disallowed when it shouldn't be.

The intent was that nobody would do anything to it.  (Of course
the new definition of const breaks that intent.)  Terms like
"modify" are controversial in the context of this discussion, and
thus not very meaningful.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>[...]
>
>| Explicit destructor calls are easy to spot.  Anyhow, nobody inserts
>| explicit destructor calls by accident, and any place they appear
>| attracts intense scrutiny.
>
>Are you suggesting a delete-expression can be inserted by accident?
>How so? Deletion is a perilous operation and everybody thinks about it
>more than once before doing it.

Two points:

1. Delete-expressions are quite common in user code, even in
   beginners' code.  Deleting the wrong pointer is a correspondingly
   common error.

2. I don't agree that "everybody" thinks twice about deleting
   pointers.  Would that it were true.

Anyway, precisely how useful the compiler's error detection once was is
a judgment call, like precisely how useful "const" is in general.  (Some
people say "const" should be a no-op everywhere.)  But I fear we are
straying from the topic: the specific fallacious arguments that were
posted repeatedly.   There are plenty to choose from, if you care to
try to defend one.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <jerrold.leichter@smarts.com>
Date: 1999/10/05
Raw View
| I am astoniched your long posting missed entirely the point.
|
| The point I was trying to make is that one defines an object 'const'
| to make a /promise/ to the compiler that it won't be changed during
| its _lifetime_ and it is up to the _creator_ to *decide* how long the
| object will live.

Please find (a) any such statement in the Standard; (b) explain how this
is relevant to the discussion at hand.

To wit:  (a)  You can always do a const-cast, so there cannot be such a
promised.  (b) The examples at hand all have to do with const pointers
or references, *not* const objects.  A function taking a const T*
doesn't create the object it receives.  By your own reasoning, it should
not be allowed to decide how long the object will live.  (For that
matter, the whole notion about the creator deciding how long an object
will live corresponds to nothing in the C++ standard.  If it didn't,
even if f() took a T*, it wouldn't be allowed to delete it.)

| One ends an object lifetime by leaving its scope or by
| deleteing it if it was newed.
|
| If constness were to imply undestructibility -- that is a destructor
| can't be called for a const object -- then how should one justify why
| it is premitted to define a const auto?

How many times do we have to go through this?  It's justified in exactly
the way that initialization of const objects is justified:  If it were
prohibited, const would not be usable.  If it makes you feel happier,
imagine that:

 { const T r;
  ...
 }

is actually implemented as:

 { T r';
  const T r& = r';
  ...
 }

where r' is a compiler-generated name.  After all, the allocated T can't
really be const - it has to be initialized, which requires writing to
the allocated memory.  To initialize it, the compiler-generated code has
to have a non-const path to it.  It's just that the program has chosen
not to provide *itself* with such an access path.

*There is no guarantee that const objects won't change.*  The only
guarantee that const has *ever* attempted to provide is that a const-
qualified access path cannot be used to change the object.

| If constness doesn't imply undestructibility, why should one have to
| go through administratives before ending a newed object's lifetime
| whereas in the auto case, one just has to leave the scope?

Who says the compiler doesn't do this for you?  After all, you don't
have to call new or delete for automatics either; the compiler generates
the code needed to get and release memory.
       -- Jerry
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/05
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>
>| Because of these fundamental differences -- lexical vs. user-managed
>| object lifetime, and implicit vs. explicit lifetime management --
>| a simple equation of auto and dynamic objects doesn't hold up,
>
>Indeed, one cannot equate 'auto objects' to 'dynamic objects'; but it
>does mean sense to make a parallel and to see how their lifetimes are
>managed.

I think everybody agrees that it can be instructive to compare and
contrast the two.

>To create an auto (non-const) object of type T, one just needs a
>definition along the lines:
>
> { // enter scope
>
>    T an_auto;
>
>to destroy it, it suffices to leave the scope
>
> } // leave scope
>
>The same scheme holds for an auto const T creation/destruction.

It is not you destroying it: the compiler is responsible for auto
objects.  You have no choice about destroying the object, just as you
have no choice about closing the scope.  The lifetime is known at
compile time.

>Now, let's see the administrative machinery for a dynamic object
>management.  I will consider only new-expression/delete-expression.
>
>In order to create a dynamic (non-const) object of type T and remember
>its address, it suffices to say
>
> T* pointer = new T; // or the appropriate form of T(...)
>
>To destroy *pointer (and to release occupied memory), a statement
>
> delete pointer;
>
>suffices.  These steps are the "common" ways to go to manage dynamic
>objects lifetime.

These appear parallel, but in use they differ fundamentally, because
the "delete pointer" can appear anywhere a copy of the pointer exists.
It might be in the same block (as in the example that sought to draw
a parallel) or it might be in some other library entirely.

It is this very real difference that makes the argument:

  { T  const t; }
  { T const* p = new T; delete p; }

fundamentally weak: it tries to draw a parallel by specifically
excluding the real-world usage pattern of dynamic objects, which
is relentlessly non-lexical.

>Now what if we want to manage a dynamic const object?  The Standard
>says the same scheme holds, e.g.
>
> T const* pointer = new const T;
>
> // ...
>
> delete pointer;
>
>Thus no additional special rule.  The ARM said one needs an extra step
>in deletion: a cast is necessary.  Why?

It sufficient to refute the argument referenced above to demonstrate that
the two cases being equated are essentially different.   Actually to argue
the case requires other arguments.

But the topic here is not whether the committee chose correctly.
(That is moot.)  The topic here is the specific arguments that
really were posted, and which may be refuted on purely logical
grounds.  That of course leaves the logically-sound (or -ambiguous)
arguments alone.

>An argument was advanced that delete-expression is going to change
>`*pointer'.  Maybe.  But the important point that argument misses is
>this:  it is true that the programmer made a /promise/ not to change
>`*pointer' directly through `pointer' during _`*pointer' lifetime_;
>but using delete-expression is the programmer's way to express that
>`*pointer' lifetime is over and occupied memroy should be released.
>What happens during delete-expression execution should not be and is
>not part of `*pointer' lifetime.

People have posted that argument.  To me it seems equally as circular
as some of those arguing for the change, because it tries to use the
definition of const to argue for a definition of const.

If you're going to justify your choice of definition of "const", you
need to refer to how proposed definitions affect coding of real
programs; but that's not what we're discussing here.

>Another argument was advanced that deletion of a pointer-to-const
>might be an accident that the compiler should prevent.  But
>deletion (of pointer-to-const or not) *is* a _perilous_ exercise that
>every programmer pays attention to and needs to be disciplined with.
>Thus it *cannot* happen accidently.

Deletion of pointers is in fact very common in user code.
Deletion of the wrong pointer is correspondingly easy.

Anyway, this is straying into discussion of not-obviously-invalid
arguments (whether const is useful), which is not the topic.

>That is why I second Francis' proposal to teach users not to
>manipulates raw pointers directly: deletion is too perilous, even with
>ARM rules.

How we teach C++ is also off-topic for this thread, because it relates
to the effect of the change on programming practices, and not to the
(in)validity of specific arguments that have been posted frequently.

>| and anyway isn't sufficient to justify what amounts to quite a
>| substantial change to the language.
>|
>| You really do need to reference something outside the rules themselves,
>
>We agree to say it was a judgment call.
>
>| and that's what makes the simple analogy to auto objects weak.
>
>If you agree that it was a judgment call, then certainly that decision
>couldn't be drawn mechanically from 'strong' logical rules

Again, let us not confuse the correctness of the committee's decision
with the correctness of specific arguments posted.  While some of the
latter are equally debatable, others were clearly fallacious.  It is
those last that are the topic.

It is clearly fallacious simply to equate lexical and dynamic lifetimes.
It is clearly fallacious to claim an analogy with Unix file permissions.
It is clearly fallacious to bring up containers of "const T".
It is clearly fallacious to promote a change by claiming benefits that
   we already had before the change.
It is clearly fallacious to promote a change by criticizing a lack that
   we still suffer after the change.
It is clearly fallacious to argue for the change without referencing any
   consequences of the change.

It may be that none of the above is immediately obvious, but each can
be explained, and demonstrated, and discussed.  After a fund of
demonstratedly fallacious arguments is in hand we can talk about
how it happened that these fallacious arguments achieved such
popularity.

I will point out again for Francis's benefit that, of course, the fallacy
of any or all of the arguments we treat does not necessarily reflect on
the correctness of the committee's decision.

>[...]
>| I still believe that incareful use of "deletion" and "destruction" has
>| confused at least some people by eliminating in discourse a very real
>| difference in reality.
>
>Perhaps I didn't make my assumptions clear.  For me, deletion is the
>common way to express a dynamic object destruction, and I thought it
>wasn't necessary to mention that.

Evidently it is necessary.  Correctness is in the details, and so are
the errors.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: 1999/10/06
Raw View
Andrew Koenig wrote:
>
> In article <sfogeep9n5.fsf@bstde026.bbn.hp.com>,
> Jens Kilian  <Jens_Kilian@bbn.hp.com> wrote:
>
> >Francis Glassborow <francis@robinton.demon.co.uk> writes:
> >> But no such example can exist because we could always have used
> >> const_cast to do the delete anyway.
>
> >You can grep for a const_cast.
>
> Not unless you have a grep that traces call chains.

The code that actually uses const_cast<> is the code that needs to be
responsible for making sure that it's use is appropriate. 'grep' on Unix
platforms will correctly locate such code. If you can't verify the
appropriateness within that body of code, you should probably re-design.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 1999/10/06
Raw View
Jerry Leichter <jerrold.leichter@smarts.com> wrote:
> If it makes you feel happier, imagine that:
>
>         {       const T r;
>                 ...
>         }
>
> is actually implemented as:
>
>         {       T r';
>                 const T r& = r';
>                 ...
>         }
>
> where r' is a compiler-generated name.  After all, the allocated T can't
> really be const - it has to be initialized, which requires writing to
> the allocated memory.  To initialize it, the compiler-generated code has
> to have a non-const path to it.  It's just that the program has chosen
> not to provide *itself* with such an access path.
>
> *There is no guarantee that const objects won't change.*  The only
> guarantee that const has *ever* attempted to provide is that a const-
> qualified access path cannot be used to change the object.

While the text above describes a proposed alternative to the current
definition of const, it does not describe what the standard currently
dictates.

Currently, const is given meaning primarily by paragraph 4 of
7.1.5.1 [dcl.type.cv]:

     Except that any class member declared mutable (7.1.1) can be
     modified, any attempt to modify a const object during its
     lifetime (3.8) results in undefined behavior.

The guarantee that const provides is that no program may rely on
changing the object.  A compiler can take advantage of this guarantee
to perform optimizations; it may not make such optimizations in
the second snippet above.

I've pointed out that a loophole in 3.8 [basic.life], while not
weakening this guarantee, can make it difficult for a compiler to
make these optimizations when the const object is dynamically allocated.
But rather than taking this to be a fatal flaw in the idea of dynamic
const objects, I'd just like to see the loophole closed.

                                                   --Lisa Lippincott


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/10/06
Raw View
In article <37FA9138.E9C6D63A@wizard.net>, James Kuyper Jr.
<kuyper@wizard.net> writes
>The code that actually uses const_cast<> is the code that needs to be
>responsible for making sure that it's use is appropriate. 'grep' on Unix
>platforms will correctly locate such code. If you can't verify the
>appropriateness within that body of code, you should probably re-design.

All this is moot because it assumes you have the source code.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/10/06
Raw View
Nathan Myers wrote:
>
> Jeff Rife  <wevsr@nabs.net> wrote:
> >Nathan Myers (ncm@best.com) wrote:
> >
> >> >OK, now, let's bring a function into play, because formal parameters to
> >> >functions are the crux of this argument.
> >>
> >> Correct.  (Though, pointers returned from functions are involved too.)
>
> I should explain further.  A key use for "old const" was in cases
> much like:
>
>   T const* f() {
>     static T t;
>     return &t;
>   }

This should have been coded as

T const& f()
{
  static T t;
  return t;
}

This way it's clear for everyone that the return value should
not be deleted (you don't call delete on pointers obtained
through the address-of operator, do you?)

>
> The point of const here is not to indicate who should delete it,
> it is to indicate that the client should *never* delete it, and
> further, if it's deleted accidentally (or assigned through) the
> compiler should forbid it.

I hope the intent was to indicate that the user should not
_modify_ it. Otherwise the interface is broken, since the
operation "f()->modify();" is disallowed when it shouldn't be.

Note that if you need a modifiable object, the reference
will still prevent accidental delete, while the pointer
version will not.

[...]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Alexandre Oliva <oliva@lsd.ic.unicamp.br>
Date: 1999/10/07
Raw View
On Oct  5, 1999, ncm@nospam.cantrip.org (Nathan Myers) wrote:

> It is this very real difference that makes the argument:

>   { T  const t; }
>   { T const* p = new T; delete p; }

> fundamentally weak: it tries to draw a parallel by specifically
> excluding the real-world usage pattern of dynamic objects, which
> is relentlessly non-lexical.

Ok, so, instead of the explicit `const' think of templates:

template <typename T> T *make_new() { return new T; }
template <typename T> void delete_it(T *t) { delete t; }
template <typename T> void do_something(T &t, ...) {
  T *another_t = make_new<T>();
  /* do something with t and *another_t */
  delete_it(another_t);
}

Now add to the Standard the rule that `delete t' is invalid if T is a
pointer to a constant object.  The templates are suddenly rendered
useless for any const T, because delete_it would be ill-formed.  And
you'd need some traits helper template class with specializations for
`const' types to be able to remove the const from T, in order to make
the delete conforming.

But then, if it becomes documented that it is possible to delete a
pointer to const, by simply applying a const_cast to it, people might
just get used to doing it, and see it as a weirdness of C++.  So why
introduce it anyway?

For safety, you say.  But pointers aren't safe.  It has always been
well-formed, albeit unsafe and undefined, to write `T t; delete &t;',
so I don't buy the safety argument.  Any safety you could derive from
such a rule it would be merely illusory, and it would certainly break
existing code, so I don't see the point of pursuing this issue any
further.

--
Alexandre Oliva http://www.ic.unicamp.br/~oliva IC-Unicamp, Bra[sz]il
oliva@{lsd.ic.unicamp.br,guarana.{org,com}} aoliva@{acm,computer}.org
oliva@{gnu.org,kaffe.org,{egcs,sourceware}.cygnus.com,samba.org}
** I may forward mail about projects to mailing lists; please use them
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/10/04
Raw View
In article <37F869ED.5509FAD2@physik.tu-muenchen.de>, Christopher
Eltschka <celtschk@physik.tu-muenchen.de> writes
>Now, if you do "delete p;", you are changing the behaviour of
>all pointers/references to the object, and therfore according
>to the definition above, the object should be considered to
>be changed. Therefore it should be forbidden for pointer to
>const.


But that argument could just as well apply to a const auto object once I
have stored its address in a pointer from a wider or different scope.

The problem with the whole of this thread is that one of the main
participants wants to discuss psychology but not philosophy (I am
reminded that my alma mater used - still does for all I know - have a
degree in Philosophy, Psychology and Economics)  Other participants want
to discuss the correctness of the decision.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/10/04
Raw View
In article <7t8nu8$vc6$1@nnrp1.deja.com>, Andrei Alexandrescu
<andrewalex@hotmail.com> writes
>But believe me, I'm open. I'd love to say one day: "Ah! Right,
>so this is a good example! Now I'm convinced!" in either direction.
>Everybody - please believe me, I'm sincere, in spite of the following
>emoticon >:o>.

But no such example can exist because we could always have used
const_cast to do the delete anyway.  The existence of delete and raw
pointers requires discipline from programmers and that is where I would
wish to focus my efforts.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/10/04
Raw View
Nathan Myers wrote in message <37f803ae$0$210@nntp1.ba.best.com>...

>The most interesting is the one that claims that a pointer-to-const
>is OK to delete because afterward the object doesn't exist, so wasn't
>really const anyway.


>From which one might conclude that the only way to ensure that an object is
really const (in an environment such as C++ that does not intrinsically
support persistence) is to ensure that the program that instantiates the
object is never allowed to terminate and that the heap is perpetual, which,
of course, is silly. Every object must be destroyed sometime. The argument
is about when and how.

>I hardly know how to discuss that in measured
>terms.  It's a howler, and it keeps getting posted.

Only because the argument that it is "logically invalid" keeps getting
posted.

I think the essence of the argument that gives you howls is that inasmuch as
the language permits you to use new to assign an address to a
pointer-to-const it must also allow you to delete through that pointer to
avoid memory leaks. That by itself is not a "logically invalid" argument. Of
course, the language always did permit that by supporting the casting away
of constness. So the argument becomes, was that way acceptable? If you
argue, "yes," then your argument is thrown back at you with the
counter-argument that the same method also can subvert the guarantee that
you cherish and that has been taken away. All of which involves opinions,
preferences, taste, style, and all those subjective things that cannot be
reasonably advanced or dismissed simply as being logically valid or invalid.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/04
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
> Nathan Myers <ncm@nospam.cantrip.org> writes
>>>Suppose we have:
>>>   delete p; // p is a pointer to a const T
>>>The compiler "magically" transforms this into:
>>>  p->~T();             // (1)
>>>  release-memory( p ); // (2)
>>>(2) is legal, trivially.
>>>(1) is legal, because: ...
>>
>>Here we have "Exhibit A" again, restated in excruciatingly erroneous
>>detail.
>
>~T() is a non const member function that can be
>called on a const object because the standard so stipulates.

Irrelevant.  T::~T() is called by the delete expression,
not by the caller of the delete expression.  The compiler itself
implements the delete expression, and can do whatever we say it
does.

The topic is whether the delete expression itself should be legal
in that context, not whether the delete expression should be allowed
to call the destructor.

>"delete" is
>a keyword that can be applied to the address of a dynamically created
>object (even if const) because the Standard says so.

That is the case now.  It was not the case before.  The argument
I dissected was trying to support the change.  You cannot argue for
the change by invoking the change.  That is a logical absurdity.
(Exhibit A, in fact.)

>The Standard could have said otherwise.

The drafts, and the ARM, did say otherwise.  The argument dissected
above was trying (and failing, as it happens) to justify the change.

> In the opinion of many that was a judgement call.

_Everyone_ agrees it was a judgment call.  That has no bearing on the
logical validity of the argument form above.

>I think that arguments based on the defined behaviour
>of delete are reasonable and defensible though not absolute.

Then why not defend them, instead of changing the subject?
Just point out something wrong in my presentation.

>Your
>characterisation says otherwise and seems to me to be the basis on which
>you believe that those who voted for the change were doing so based on
>fallacious arguments.

Francis, you cannot refute an argument by impugning the motives
of the arguer.  (Andrew just posted a long explanation why not.)
The arguments stand or fall on their own merit.  Thus far, when
actually examined, they fall.

>I do not think we can make any further progress on this issue.

Changing the subject also does not refute the argument.

>From the perspective of programmers, they should be taught that they
>should never apply delete to a pointer unless they know that the pointer
>'owns' the object pointed to.  That is best done by some form of smart
>pointer.

"What we should teach" is _also_ irrelevant to the logical validity
of the argument dissected above.

>I have frequently argued that the appearance of delete in client code
>is always suspect, and like a cast should always be justified and
>commented.

What you have frequently argued has nothing to do with the argument
you claim to be refuting.

Are Francis's remarks above the best we can do?
Can anybody please actually take on defending the argument?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/04
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

| Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
| >
| >The point I was trying to make is that one defines an object 'const'
| >to make a /promise/ to the compiler that it won't be changed during its
| >_lifetime_ and it is up to the _creator_ to *decide* how long the object
| >will live.  One ends an object lifetime by leaving its scope or by
| >deleteing it if it was newed.
|
| Two points:
|
|  1. Declaring an object "const" and declaring a "pointer-to-const"
|     are very, very different things.  The issue at hand is not
|     destruction of const objects, but the delete-expression
|     applied to certain pointers.

Don't worry, I am well aware of the issue at hand.

|  2. One declares a pointer-to-const to encourage the compiler to
|     diagnose violations of constness, and to help guide the compiler
|     to overloads and specializations for const arguments.

I agree.

[...]

| >If constness were to imply undestructibility -- that is a destructor
| >can't be called for a const object -- then how should one justify why
| >it is premitted to define a const auto?
|
| Constness has never implied undestructibility, and it doesn't now, so
| the change to const semantics had nothing to do with that.  It _did_
| imply undeleteability, and no longer does.  Discussing destruction
| in this context is a confusion of categories.

No, I'm not trying to confuse anyone (including myself of course :-).
I'm trying to analyze why one uses delete-expression.  Destruction of
an object on heap (and release of the associated memroy) is usually
the main reason.

| >If constness doesn't imply undestructibility, why should one have to
| >go through administratives before ending a newed object's lifetime
| >whereas in the auto case, one just has to leave the scope?
|
| Again, because we're talking about the delete-expression, which does
| not apply to auto objects.  You don't have any choice about the lifetime
| of auto objects: it is purely lexical, and the compiler takes care of
| running the destructor.

Again using delete-expression is the way one goes in order to destroy
an object and to release associated memory.  The compiler takes care
or running the destructor.  The main difference is the control of the
object lifetime, and this is entirely under the programmer's control.
Thus my initial query: why should he have to go round an assault
course before destroying the object (and releasing the occupied
memory)?
Notice that I'm seeing the destruction as the *desired* effect of
deletion.

|
| For the case of dynamic objects, it is a choice you make as a programmer,
| and the issue is purely of whether a const_cast should be necessary in
| order to delete a pointer-to-const.

Right now, we're in full agreement.

| ...   As Andrew is at pains to repeat
| frequently, it is a judgment call.  Such a judgment should be (and should
| have been) made based on analysis of the effect on real programs and
| programmers, not on sterile arguments that have been proposed to settle
| the argument without any real-world analysis.
|
| That the purely-abstract arguments advanced in this case have all betrayed
| fundamental confusions is extremely interesting.  Since the language will
| not be changed, any issue of what decision the committee should have made
| is moot, but the enormous holes in the arguments presented remain worthy
| of study.

Before stating there are confusions, perhaps would you want to make sure
there are *really* confusions, not just divergence from your point of
view, nor analysis of the opponents' point of view.

I'm not trying to convince people that the change was right or wrong.

I'm trying to analyze your opponent's arguments instead of
peremptorily ordering that their arguments are logically unsound, or
purely-abstract.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Dennett <james@jamesd.demon.co.uk>
Date: 1999/10/04
Raw View
>
> Arguments that assume their conclusion are always invalid.  The argument
> that it should be OK to delete a pointer-to-const because after deletion
> the object doesn't exist (and therefore can't be const) is a particularly
> confused example of this.

Some people clearly have trouble understanding this argument, and fail to
respond when it is explained to them, merely repeating their
misunderstanding.

When you feel that an argument is clearly wrong, consider whether (a) you
are misunderstanding the argument, or (b) your counter-argument is itself
unconvincing or even wrong.

The argument is, roughly, that "delete p" ends the lifetime of the object to
which p pointer, and is the (moral) equivalent for a dynamically allocated
object of causing a stack object's lifetime to end by closing the scope
which contained its declaration.  Both of these are distinct from calling
the object's destructor, but both imply it.

There is no need to assume that it was legal to call "delete p" in order to
conclude that "delete p" is reasonable.  It's more of an argument by
symmetry: if it's *reasonable* to end the lifetime of a const object which
is on the stack then it should be reasonable to end the lifetime of a const
object which is on the heap.  "delete p" is not legal because the object
will not exist after the call.  It's legal because there's no contradiction
there (delete p is a language construct, not a call to a non-const method),
and the only debate is when during the process of deletion the object's
lifetime ends.

If anyone truly feels that any argument for "delete p" has relied on the
conclusion (that the object will have been destroyed) in order to argue its
case, maybe they would care to exhibit an argument to explain their
viewpoint.  So far I have seen only "proof by intimidation" -- maybe a good
way to show that all horses have an infinite number of legs, but no way to
discuss language features.

Maybe the fact that we don't actually have a const object on the heap is
relevant here: what we are talking about is a pointer to const, where the
static type of the object which is pointer to is not const.  What I care
about, though, when I declare something like "const Foo *p = new Foo;" is
that my Foo object should be immutable (unless this guarantee is
circumvented by use of a const_cast) so that in effect I have a "const
Foo".  So, I consider it reasonable to say that "delete p" (where p is of
static type "const Foo *") is the equivalent of allowing an object on the
stack to fall out of scope.

> Arguments that simply try to change the subject are invalid.  (The
> moderators would probably be annoyed by my favorite examples of this.)
>
> Under normal circumstances the invalid forms presented above do not
> appeal to experienced people.  I wish somebody would suggest how and
> why that fails in this instance, instead of just repeating the
> invalid arguments at louder volume, criticizing me personally, or
> quoting Ayn Rand.

I'm trying -- your perception that all of the forms may be invalid may
itself be based on flawed reasoning, or on solid reasoning on top of flawed
assumptions.  Wouldn't it be good to be sure that your arguments (or
meta-arguments?!) are sound before stating in black-and-white terms that the
logic of other contributors to this group is fundamentally broken?

(Maybe some interested parties could this off-group and then return it to
the outside world when the obvious disconnect has been resolved?)

-- James Dennett <jdennett@acm.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/04
Raw View
Al Stevens <alstevens@midifitz.com> wrote:
>Nathan Myers wrote
>
>>The most interesting is the one that claims that a pointer-to-const
>>is OK to delete because afterward the object doesn't exist, so wasn't
>>really const anyway.  I hardly know how to discuss that in measured
>>terms.  It's a howler, and it keeps getting posted.
>
>Only because the argument that it is "logically invalid" keeps getting
>posted.
>
>I think the essence of the argument that gives you howls is that
>inasmuch as the language permits you to use new to assign an address to a
>pointer-to-const it must also allow you to delete through that pointer to
>avoid memory leaks.

No, that's not the argument.  You just described the status quo both
before and after the change.  The essence of the argument is (as stated
by Siemel):

> > ... at the "delete ptr", the object pointed to by
> > 'ptr' no longer exists and so it matters not whether the object is
> > const or not.

This is the logical equivalent of plugging a power strip into itself.
It tries to decide the issue based on a self-reference, rather than
on the consequences of the change.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/10/04
Raw View
In article <37f80177$0$214@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>Such a judgment should be (and should
>have been) made based on analysis of the effect on real programs and
>programmers,
And what makes you think it wasn't?  You have absolutely no idea what
caused individuals to vote one way or another.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/10/04
Raw View
In article <37f451b4$0$203@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>Are Francis's remarks above the best we can do?
>Can anybody please actually take on defending the argument?

You ask for logical arguments defending a judgement call.  I do not
think such can exist or there would not be a judgement call to make.
You stated that you were puzzled by the decision of the Standards
Committees to change the rule because you found the reasons
unconvincing.  IOWs you would have made a different call.  Fine, you are
entitled to that opinion, but each and every Committee member is also
entitled to their call.  Judgement calls are often based on experience.

You have claimed, IIRC, that the Committee acted illogically in making
the change, or were swayed by illogical arguments.  I maintain that the
onus is on you to demonstrate that they were swayed by illogical
arguments.  I simply do not think you can do that.  You are entitled to
believe they were but equally I am entitled to believe they were not.  I
do not need to defend any argument because my position is that you
cannot arrive at a judgement call by exercising logic.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/04
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>
> Christopher Eltschka <celtschk@physik.tu-muenchen.de> writes
>>Now, if you do "delete p;", you are changing the behaviour of
>>all pointers/references to the object, and therfore according
>>to the definition above, the object should be considered to
>>be changed. Therefore it should be forbidden for pointer to
>>const.
>
>But that argument could just as well apply to a const auto object once I
>have stored its address in a pointer from a wider or different scope.

Nobody has any choice about when an auto object goes out of scope,
and its lifetime ends.  The entire issue is about what kind of
controls to place on ending the lifetime of dynamic objects.

>The problem with the whole of this thread is that one of the main
>participants wants to discuss psychology but not philosophy ...
>Other participants want to discuss the correctness of the decision.

Assuming that Francis refers to me, I am not interested in either.
Further, Francis himself has remarked that discussing the correctness
of the decision was pointless.

I am interested in the fallacious arguments that influenced the decision
to change.  If you must question motivation, I am interested in collective
decision processes that go awry.  None of this depends on the decision
in question being wrong; it is sufficient that the participants point
to logically invalid arguments to justify their decision.

To say "We changed X so we would have Y" is logically nonsensical if you
already had Y before the change, or you still don't have Y afterwards.

This is the level of logical error I am calling attention to, and I
stand amazed that anybody would post the same arguments again even after
the error is pointed out, or claim there is nothing wrong with it, or
even criticize me personally for saying there is.  I had thought to
conduct a port-mortem, but the patient won't even lie down!

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/10/05
Raw View
Nathan Myers wrote:

> The most interesting is the one that claims that a pointer-to-const
> is OK to delete because afterward the object doesn't exist, so wasn't
> really const anyway.

???

> I hardly know how to discuss that in measured
> terms.  It's a howler, and it keeps getting posted.

Non-sens. A pointer to const is really const over the
_lifetime_ of the pointed to object. When you end the
lifetime of the object, const stop making sens.

Passing a const pointer to a function guaranties that it
won't try to modify the object w/o a cast over its lifetime
through this pointer (of course, it could through another
non const pointer pointing to te same object).

Passing a pointer to const currently does _not_ guaranty
that the called function won't end the lifetime of the
object, making all other pointers/references to the
object unusables.

Nathan, you can understand that. I have already given you
two definitions of const, so that you could tell the one
you prefer. If you choose the ``referee remains valid''
definition, then you won't accept the argument presented
in this message. Still, I am sure you can _understand_ it.

--

Valentin Bonnard
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Hyman Rosen <hymie@prolifics.com>
Date: 1999/10/03
Raw View
Jerry Leichter <jerrold.leichter@smarts.com> writes:
> The *programming* issue - as described in an old comment of Dennis
> Ritchie's that someone re-posted recently - comes down to just why you
> would declare something const to begin with.  There are really only
> three possible reasons:  (1) Purely as an annotation for readers of the
> program about the intended use of the thing being declared; (2) to make
> some assertion about the program that the compiler will ensure is
> maintained; (3) to allow additional optimizations.

You missed one -

(4) To allow a temporary object to be passed by reference.

This leads to the use of const where people would be just as happy
to use non-const. If they then have to pass a pointer to this parameter
to another function, we have that (const T *) argument.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Mike Enright <enrightm@acm.org>
Date: 1999/10/03
Raw View
ark@research.att.com (Andrew Koenig) wrote:

>
>Nathan Myers' continued insistence that any arguments with which he
>disagrees are ``logically invalid'' is a sterling example of this technique.
>Its continued use prevents all possibility of rational discussion,
>so there is no point in continuing to try.  All that can possibly result
>is a restating of the same positions, at successively higher volume,
>with no true insight or understanding.

I have patiently read some hundreds of messages on this topic. I have
yet to be convinced that the way the Standard turned out on this issue
was an improvement over what ARM said.

I understand that the change facilitated a certain idiom in templates
when those templates had certain types as their arguments. I also
understand that certain idioms in existing code can no longer be read
as they once were read:

void f(const t* x);

was once (a) unlikely to delete what x pointed to (b) if all the code
was subject to a scan for, and close questioning of, all casts, then f
would have certainly not deleted what x pointed to. The author of such
a function f would have had to use a const_cast, and at the very least
the system would have been refactored. Now, a cast will not be
required in deleting what x points to, so it will take more time to
scrutinize code where pointers to const objects are used. On the other
hand, it is my understanding that in the relatively infrequent
occasions when we write templates, we will have to spend slightly less
time getting them to handle certain types.

To respond directly to the Koenig comment, I will add that I don't
feel intimidated into this understanding. Maybe my perception of the
way we should work when we write functions or methods (don't surprise
the other programmers) and my perception of the way C++ mostly works
leads me to expect any rules about deleting const objects to say what
the ARM happened to say rather than what the Standard says. Then I
consider the generally positive effects of 'const' on programming in
the large, and I am discouraged that the Standard turned out as it
did.

Not everyone appreciates Rand, so dragging her name in might be
considered poisoning one's own well, regardless of how astute or
germane.


--
Mike Enright
enrightm@acm.org (Email replies cheerfully ignored, use the news group)
http://www.users.cts.com/sd/m/menright/
Cardiff-by-the-Sea, California, USA


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/03
Raw View
Jerry Leichter <jerrold.leichter@smarts.com> writes:

| | | | In that case how can a destructor ever be applied to a const auto
| | | |or
| | | | static object?
| | |
| | | This topic has been discussed before - on reason this discussion
| | | goes on
| | | forever is that its history is repeatedly erased.
| | |
| | | Your question actually has two real questions underlying it:
| | |
| | | 1.  If I write:
| | |
| | |       {       const T t;
| | |               ...
| | |       }
| | |
| | | how would t ever get destroyed (destructed and its memory released)
| | | if delete can't be applied to a const object?  (The question for
| | | statics is identical.)
| |
| | Whereas there have been lengthy postings on this issue, I still fail
| | to see why const should imply /undestructible/.
|
| Do you want to discuss philosophy, or do you want to discuss
| programming?  Whether const implies undestructibility is philosophy.

Well, if I wnat to discuss philosophy I know where to send my
posting.  If I sent it here, it presumably because I want to discuss
Programming.

[...]

| | If 'const'ness implies undestructibility, then const autos should be
| | classified ill-formed, for the sake of consistency.
|
| Pardon me, but that reminds me of the statement that some assertions are
| so foolish that only a intellectual could believe them.

Nice flame.

| ... Why not argue
| that, "for consistency", constructor's shouldn't be allowed to
| initialize const members?  Or that functions calls shouldn't be allowed
| to initialize const formals?  After all, const says "doesn't change"; it
| doesn't say "changes only once".  So are you ready to eliminate const
| from the language entirely?

I am astoniched your long posting missed entirely the point.

The point I was trying to make is that one defines an object 'const'
to make a /promise/ to the compiler that it won't be changed during its
_lifetime_ and it is up to the _creator_ to *decide* how long the object
will live.  One ends an object lifetime by leaving its scope or by
deleteing it if it was newed.

If constness were to imply undestructibility -- that is a destructor
can't be called for a const object -- then how should one justify why
it is premitted to define a const auto?

If constness doesn't imply undestructibility, why should one have to
go through administratives before ending a newed object's lifetime
whereas in the auto case, one just has to leave the scope?

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1999/10/03
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

>Why people found (and continue to find) logically invalid arguments
>persuasive is really interesting to me.

I don't think the arguments in question are all logically invalid.
However, the people presenting them may not have stated all of
their assumptions.  The difference in opinions may arise because
different people are working with different sets of assumptions.

--
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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Andrei Alexandrescu <andrewalex@hotmail.com>
Date: 1999/10/04
Raw View
In article <FIuM3y.3HG@research.att.com>,
  ark@research.att.com (Andrew Koenig) wrote:
> I believe that this discussion is a good example of what Ayn Rand
calls
> an ``argument from intimidation.''  She described it in the
Objectivist
> Newsletter, Volume 3, no. 7, in July 1964.  It would be inappropriate
> for me to quote the entire article, but a few short quotes should
> give enough of an idea:

[snip]

I agree with Mike Enright. IMHO even the short quotes you presented are
inappropriate.

First, I don't think anyone tried such a manipulation, second, not
everyone here is a fan of Ayn Rand (I'm not) - which renders your
exposition useless given that you assume she's an authority to be
quoted in this context -, third, I don't quite think the idea in itself
is new or even very interesting (Stalin is well known for manipulating
people like this, for instance by saying: "You have to be an imbecil
not to see how great communism is, given that we achieved this and
that"), and fourth, er,... er,... I forgot :o).

Note to moderators: please enter me automagically to the contest "The
longest sentence on csc++. The paragraph before consists of one
sentence only.

Getting back to the issue, my feeling is that "delete const" opposants'
point is quite clear. On the other hand, I'd be happy to see a clear
example where the new rule leads to simpler, better, more elegant code.
No dot-dot-dot. A *real* example. An example that would raise eyebrows
if the ARM rule was assumed. An example really ugly with ARM rules. And
then let's compare the advantages and disadvantages of the two
tradeoffs.

> Its continued use prevents all possibility of rational discussion,
> so there is no point in continuing to try.  All that can possibly
result
> is a restating of the same positions, at successively higher volume,
> with no true insight or understanding.

I'd be happy to see a compelling example in favor of the Standard rule.
After all, it's the Standard and we have to go for it :o). I don't
think that arguments in favor of "delete const" are illogical. Call me
dense, but even after all this long thread, I couldn't collect a clear
exposition in favor of "delete const". I have to admit, though, that
I've collected quite a consistent body of arguments against "delete
const". But believe me, I'm open. I'd love to say one day: "Ah! Right,
so this is a good example! Now I'm convinced!" in either direction.
Everybody - please believe me, I'm sincere, in spite of the following
emoticon >:o>.

I'm sure I'm wrong somewhere, but frankly, my feeling now is that the
main argument in favor of "delete const" revolves around an increased
difficulty in explaining some unclear examples that are likely to occur
rarely, can be solved in a number of ways, and are not of the
contingent of begginership anyway.

I obviously forgot to ingest the "short sentences" pill this morning.
Sorry.


Andrei


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/04
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>
>Whereas there have been lengthy postings on this issue, I still fail
>to see why const should imply /undestructible/.
>
>If 'const'ness implies undestructibility, then const autos should be
>classified ill-formed, for the sake of consistency.

Gabriel's clear statement reveals the essential confusion
underlying much of the disagreement in this thread.  Constness
does not, and never did, imply undestructibility.

Deletion is not the same as destruction.  Every object gets
destroyed, but only free-store objects get deleted first.

The mandated change to const semantics only affected rules for
_deletion_, not _destruction_.  In particular, it affected what
the compiler must do in response to a *delete-expression* --
not to be confused with a destructor call or a call to operator
delete().

Clear?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/04
Raw View
Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>
>>Why people found (and continue to find) logically invalid arguments
>>persuasive is really interesting to me.
>
>I don't think the arguments in question are all logically invalid.
>However, the people presenting them may not have stated all of
>their assumptions.  The difference in opinions may arise because
>different people are working with different sets of assumptions.

It is sufficient for the sake of discussion that most, or some,
of the arguments posted repeatedly are logically invalid.  The
ones that aren't are less interesting.

The most interesting is the one that claims that a pointer-to-const
is OK to delete because afterward the object doesn't exist, so wasn't
really const anyway.  I hardly know how to discuss that in measured
terms.  It's a howler, and it keeps getting posted.

Most of the other arguments posted claim to support the change by
describing some feature present after the change, neglecting that
the same feature was equally available before the change.  The
"container of const T" arguments are in this category.

I agree that sometimes assumptions differ.  Unstated assumptions
can also be false, though, such as the assuption that the delete-
expression and destruction (which may underlie the howler above?)
are the same thing.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/04
Raw View
Dave Harris <brangdon@cix.co.uk> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) wrote:
>> The issue (trying to be) under discussion is how such arguments can
>> seem persuasive to intelligent people.
>
>... Do you have any insights you want to share?
>You seem to have given it more thought than anyone else.

I keep hoping that somebody who used to find one or other of the
arguments persuasive can say why they did.

It would be very insulting to suggest that people will accept (even
defend) any argument in favor of what they want, regardless of how
senseless the argument.  I would be very disappointed to find that
the case here, and keep hoping something more interesting will be
revealed.

>For what it's worth, the issue reminds me a little of Plauger's
>meta-discussion of malloc(0), in his book "Programming On Purpose II".
>Much of the base discussion revolved around two arguments, labelled by
>Plauger:
>
>    16+ Zero should behave like any other number.
>    16- Zero is a special case, different from any number.

As here, a case can be made for either alternative, and what matters
is the effect on real programs.  It is interesting that your example
also concerns dynamic objects; is it reasonable to guess that most
arguments presented ignored real programming consequences, as here?

>To me, the idea that "delete p" changes *p and so should be forbidden if
>*p is const, is so obvious that it takes real mental effort to explain
>why. But for other people, the opposite is apparently equally opposite
>and they too have trouble explaining why.

To me it is not at all obvious, and we must look at the effect on
system design to see the effects of the alternatives.  Most claims
asserted in this forum don't bear scrutiny in that light.

Interestingly, most don't bear scrutiny even on their own terms.

For example, a claim that "change X is good because Y is now possible"
is invalid if Y was possible before change X.  Arguments that "it
should be possible to destroy what you create", and "it should be
possible to make containers of 'const T'" are examples of this.

For another example, a claim that "change X is good because construct Y
was impossible" is invalid if construct Y is still impossible after the
change.  Arguments "it should be possible to make STL containers of
'const T'", and "it should be possible to mark pointers-to-nonconst
as undeleteable" are examples of this form.

Arguments that assume their conclusion are always invalid.  The argument
that it should be OK to delete a pointer-to-const because after deletion
the object doesn't exist (and therefore can't be const) is a particularly
confused example of this.

Arguments that simply try to change the subject are invalid.  (The
moderators would probably be annoyed by my favorite examples of this.)

Under normal circumstances the invalid forms presented above do not
appeal to experienced people.  I wish somebody would suggest how and
why that fails in this instance, instead of just repeating the
invalid arguments at louder volume, criticizing me personally, or
quoting Ayn Rand.

We may be led to an uncomfortable truth, but isn't that better than a
comfortable falsehood?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/10/04
Raw View
Dave Harris wrote:
>
> ncm@nospam.cantrip.org (Nathan Myers) wrote:
> > The issue (trying to be) under discussion is how such arguments can
> > seem persuasive to intelligent people.
>
> Actually, you're the only person who seems to want to discuss this. Do you
> have any insights you want to share? You seem to have given it more
> thought than anyone else.
>
> For what it's worth, the issue reminds me a little of Plauger's
> meta-discussion of malloc(0), in his book "Programming On Purpose II".
> Much of the base discussion revolved around two arguments, labelled by
> Plauger:
>
>     16+ Zero should behave like any other number.
>     16- Zero is a special case, different from any number.
>
> To me, the idea that "delete p" changes *p and so should be forbidden if
> *p is const, is so obvious that it takes real mental effort to explain
> why. But for other people, the opposite is apparently equally opposite and
> they too have trouble explaining why.

Maybe an explanation why "delete p" changes "*p" could be as
following:

For a dynamic object, the only way to access it are pointers
and references. Moreover, we can view variables as a special
type of reference which is automatically bount to a new
object with lifetime equal to the variable lifetime. With this
view, we can see all objects just through pointers and
references.
Now the only way we can watch changes to objects is by
looking at the objects through references. Now if we change
a pointer, the result of dereferencing this pointer
does change (including to undefined behaviour, if we set
it to NULL or to a one-past-end value), but the result of
dereferencing all other pointers and references is unchanged.
OTOH, if we change the object pointed to by a pointer or
referenced by a reference, then the result of dereferencing
each single pointer/reference to this object is changed.
Since with the above view, the object is only seen through
references, one could define "change of the object" as
"change of the behaviour of accessing through _any_ pointer
or reference". (With this definition, one cannot distinguish
between changing the only pointer to an object, and changing
the object it points to - but indeed, no conforming program
can distinguish that, because to check, you'd need a second
pointer to compare your first one to.)

Now, if you do "delete p;", you are changing the behaviour of
all pointers/references to the object, and therfore according
to the definition above, the object should be considered to
be changed. Therefore it should be forbidden for pointer to
const.

Indeed, exactly that behavior - that it affects _other_
pointers/references to that object - is the reason why one
would like to prohibit deleting. If "delete p" only affected
the pointer "p" itself, then it would be harmless.

BTW, even with "delete p" forbidden for const pointers,
"nodelete" on non-const pointers could be useful, as a way
do prevent only "fatal" modifications.
Note that a similar case could be made for "public" and
"protected", where you cannot express the desire
"I want this to be accessible by the outside world, but not
by derived classes". Of course anyone would agree that this
is an useless option, and therefore it doesn't hurt that we
don't have it. But logically, access by derived objects and
access by the rest of the world are logically distinct
concepts (as the existance of "protected" proves). Therefore
one could argue logically that you can restrict derived
class access and outer world access separately, and so
"public" should not include "protected", but you should
be able to provide both at the same time.

The "nodelete" modifier in the "no delete for const"
case would be a sort of "weaker const", just as "protected"
is a sort of "weaker private". That is, it would not be a
separate attribute, but an additional protection level
in the const range, between const and non-const.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/04
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>
>The point I was trying to make is that one defines an object 'const'
>to make a /promise/ to the compiler that it won't be changed during its
>_lifetime_ and it is up to the _creator_ to *decide* how long the object
>will live.  One ends an object lifetime by leaving its scope or by
>deleteing it if it was newed.

Two points:

 1. Declaring an object "const" and declaring a "pointer-to-const"
    are very, very different things.  The issue at hand is not
    destruction of const objects, but the delete-expression
    applied to certain pointers.

 2. One declares a pointer-to-const to encourage the compiler to
    diagnose violations of constness, and to help guide the compiler
    to overloads and specializations for const arguments.  Breaking
    const in that context only affects whether you can get reports
    of violations; now, you can't.

>If constness were to imply undestructibility -- that is a destructor
>can't be called for a const object -- then how should one justify why
>it is premitted to define a const auto?

Constness has never implied undestructibility, and it doesn't now, so
the change to const semantics had nothing to do with that.  It _did_
imply undeleteability, and no longer does.  Discussing destruction
in this context is a confusion of categories.

>If constness doesn't imply undestructibility, why should one have to
>go through administratives before ending a newed object's lifetime
>whereas in the auto case, one just has to leave the scope?

Again, because we're talking about the delete-expression, which does
not apply to auto objects.  You don't have any choice about the lifetime
of auto objects: it is purely lexical, and the compiler takes care of
running the destructor.

For the case of dynamic objects, it is a choice you make as a programmer,
and the issue is purely of whether a const_cast should be necessary in
order to delete a pointer-to-const.  As Andrew is at pains to repeat
frequently, it is a judgment call.  Such a judgment should be (and should
have been) made based on analysis of the effect on real programs and
programmers, not on sterile arguments that have been proposed to settle
the argument without any real-world analysis.

That the purely-abstract arguments advanced in this case have all betrayed
fundamental confusions is extremely interesting.  Since the language will
not be changed, any issue of what decision the committee should have made
is moot, but the enormous holes in the arguments presented remain worthy
of study.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Andrei Alexandrescu <andrewalex@hotmail.com>
Date: 1999/10/04
Raw View
In article <F0+UhQAOYn83Ew2H@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
> Unless you can explain how const auto and const static objects can
have
> a non-const member (dtor) called on them I think any further
discussion
> is vacuous.

I'm afraid you're not right here, Francis. We all know the compiler is
allowed to do things that a programmer cannot do. My favorite example
is: simulate in C++ the code that's generated for the creation of a
local static object.

This point was also enforced by Jerry Leichter, who said: *no one ever
said the operation of compiler-generated code could be expressed in
legal C++*.

I think this point renders yours moot. Of course, this is only my
opinion.

The particular fact that destructors can be called by hand is an
anomaly that should not be perpetrated and used as an example in favor
of allowing "delete const". It's like saying: "there is a problem in
there, then why not allowing the second"?

Thinking of const in an overly strict way would start a holy war that
would raise a bunch of questions about initialization, const members,
and so on.

Andrei


Sent via Deja.com http://www.deja.com/
Before you buy.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/10/04
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

| Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
| >
| >Whereas there have been lengthy postings on this issue, I still fail
| >to see why const should imply /undestructible/.
| >
| >If 'const'ness implies undestructibility, then const autos should be
| >classified ill-formed, for the sake of consistency.
|
| Gabriel's clear statement reveals the essential confusion
| underlying much of the disagreement in this thread.  Constness
| does not, and never did, imply undestructibility.
|
| Deletion is not the same as destruction.  Every object gets
| destroyed, but only free-store objects get deleted first.
|
| The mandated change to const semantics only affected rules for
| _deletion_, not _destruction_.  In particular, it affected what
| the compiler must do in response to a *delete-expression* --
| not to be confused with a destructor call or a call to operator
| delete().
|
| Clear?

Well, it was clear for me and I didn't and don't confuse deletion and
destruction.  Deletion implies destruction.

As I explained in another posting, an auto object lifetime is ended by
leaving its scope.  The `usual' way to destroy an object *and* to
release associated resources is to use a delete-expression.  The
point I was trying to make is that one does not have to go through
complicated administrative machinery (casting) in order to destroy
an auto object and release associated resources: one just leaves the
scope.  Similary one should not go round an assault course
(const_casting) in order to destroy an object on heap and release
associated resources.

As you can notice, I wasn't confusing destruction and deletion.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/10/04
Raw View
In article <37f7f16a$0$207@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>Deletion is not the same as destruction.  Every object gets
>destroyed, but only free-store objects get deleted first.

I almost agree with everything apart from the last word.  Freestore
objects can be destroyed via either calling delete (and their
destruction is then part of that, the first part to be precise) or by an
explicit call to the destructor.  It is the second of those options that
punches a gapping hole through the concept of const.  We can explicitly
call the dtor on an object and then use placement new to construct a
similar but not necessarily identical (in the sense of having an
identical state) object in its place.  According to my (perhaps
erroneous) understanding this process is well formed according to the
Standard.  It is also even harder to detect source code than simple uses
of delete.

The first option I referred to above is not something that happens
before destruction, destruction is a necessary part of any use of
delete.  From my perspective, once you can explicitly destroy a const
object the genie is out of the bottle and the rest is just playing word
games to provide some illusion of extra safety.  The problem with
illusions is that the get in the way of learning (not to try to delete
things you do not own, because the compiler will look after you).

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@best.com (Nathan Myers)
Date: 1999/10/01
Raw View
In article <MPG.125c4864b48bc6e098970f@news.nabs.net>,
Jeff Rife  <wevsr@nabs.net> wrote:
>Nathan Myers (ncm@nospam.cantrip.org) wrote:
>
>> I should explain further.  A key use for "old const" was in cases
>> much like:
>>
>>   T const* f() {
>>     static T t;
>>     return &t;
>>   }
>>
>> The point of const here is not to indicate who should delete it,
>> it is to indicate that the client should *never* delete it, and
>> further, if it's deleted accidentally (or assigned through) the
>> compiler should forbid it.
>
>Right.  And my statement later in this post agrees with you, but not
>about the const part.
>
>Basically, if you can't delete const pointers, then a library can't
>return an object to you that you can't modify, yet must clean up ...

False.  Pointers-to-const can be converted into pointer-to-non-const,
and deleted.  The conversion can be placed where it is safe.  A minimal
example:

  class Bozo {
    public:
      static Bozo const*
        bozo_factory() { return new Bozo; }
      void dispose() const { delete const_cast<Bozo*>(this); }
    private:
      ~Bozo();
  };

A Bozo user has no need to apply casts, nor ever to delete a
pointer-to-const.

>> With older compilers, I get a compile-time error message.
>
>Only because of the const, *not* because of the fact that you can't
>*ever* delete this structure.

Precisely, because of the const.  That was what it was for, and that
was what it did.  Nobody has argued that it should be impossible to
delete things.

>> Your mistake, here, is the same as Andrew's.  The lack of a const
>> never told you anything, but the presence of a const was a clear
>> message: don't delete.
>
>Not necessarily.  It might have told me "don't change, but the stupid
>compiler won't let you delete it, either, so live with the it".

In fact you have always been able to delete any dynamic object.

>With the old const meaning, systems had to be designed so that anything
>logically const that was handed out dynamically (using new) was *not* a
>limited resource, because long-running programs (daemons, etc.) would
>eventually eat them all up, as they could not free them.

False.

>On the reverse, anything that a system wanted to allow to be deleted must
>be non-const, and thus *must* be in memory that is writable by the program
>that uses it.  Otherwise, you have the reverse problem, where the docs
>must say "don't write to this, but it is safe to delete it".  This is
>*exactly* the same situation as "don't delete this, but it is safe to
>write to it".  Both are declared the same way in ARM-compliant compilers.
>
>No matter what you make const mean on the compiler, it always comes down
>to RTFM to see what you truly can do with any pointer returned from a
>library you don't control.

Nobody ever said don't RTFM.  The issue was always whether the compiler
would issue an error message if (when) you got it wrong.  Now it doesn't.

But all this is moot.  We already have plenty of fallacious arguments
to dissect, and don't need any more (or valid ones, either).

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/10/01
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>Nathan Myers <ncm@nospam.cantrip.org> wrote:
>>Andrew Koenig <ark@research.att.com> wrote:
>>>In order to claim that const has been broken, according to Nathan's
>>>definition of `broken,' you have to exhibit a complete program
>>>that used to work and now fails.  An isolated fragment isn't enough.
>
>>I didn't make any requirement of "complete programs" in my definition.
>>... A language change which results in a change to a library's "interface
>>guarantees" has certainly broken that library, regardless of its
>>effects on the complete programs already using that library.
>
>As you yourself have pointed out, there has been no change to any
>library's ``interface guarantees.''

No, in fact I did not point out any such thing.

>For example, [ example which does not illustrate the problem ]
>If [contrafactual] then I might be more inclined to disagree with you.

I don't mind if Andrew disagrees with me.

>What you seem to be saying is that the change broke code because a caller
>of f used to be able to rely on f not deleting the object given to it,
>but if f is rewritten after the change, that reliance goes away.

No, that is not what I am saying.

>So I stand by my claim:  Nothing has been broken by the change.

Andrew, you are most welcome to stand by any claim you like.

However, if you insist that only the most minimal measure of
"breakage" can be meaningful, you will find yourself at odds with
the mainstream of software engineering, which identifies many
different such measures.

Still, "const" _was_ broken, because its semantics _were_ changed.

If Andrew finds himself unable to discover an engineering case in
which this change had any effect, that indicates more about his
inclination to explore the matter than about the matter itself.

Anyhow, there's little point in quibbling over a minor word choice.

I'm happy to say that const was "changed" and get back on-topic:
-- the repeated posting of a small group of logically-unsound
arguments in favor of the change, to the (near-?) exclusion
of the logically-sound ones.

Perhaps somebody would care pick one to defend, by some means other
than repetition or assertion of cultural relativity?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jerry Leichter <jerrold.leichter@smarts.com>
Date: 1999/10/01
Raw View
| | | In that case how can a destructor ever be applied to a const auto
| | |or
| | | static object?
| |
| | This topic has been discussed before - on reason this discussion
| | goes on
| | forever is that its history is repeatedly erased.
| |
| | Your question actually has two real questions underlying it:
| |
| | 1.  If I write:
| |
| |       {       const T t;
| |               ...
| |       }
| |
| | how would t ever get destroyed (destructed and its memory released)
| | if delete can't be applied to a const object?  (The question for
| | statics is identical.)
|
| Whereas there have been lengthy postings on this issue, I still fail
| to see why const should imply /undestructible/.

Do you want to discuss philosophy, or do you want to discuss
programming?  Whether const implies undestructibility is philosophy.

The *programming* issue - as described in an old comment of Dennis
Ritchie's that someone re-posted recently - comes down to just why you
would declare something const to begin with.  There are really only
three possible reasons:  (1) Purely as an annotation for readers of the
program about the intended use of the thing being declared; (2) to make
some assertion about the program that the compiler will ensure is
maintained; (3) to allow additional optimizations.

If I have:

 f(const T*);

 { T* t = new T;

  t->x = 1;
  f(t);
  assert(t->x == 1);
 }

can I assume the assertion always true?  The answer in C++ has always
been no, but it's been no in the same way that assertions about the
internal consistency of t - as determined by its constructors and public
interface - have not necessarily been maintained.  The latter requires
that f() doesn't subvert the type system by using reinterpret_cast (or
some forms of static_cast.)

The former similarly requires that f() doesn't subvert const-correctness
(a particular piece of the type system) by using const_cast.  Note that
the new-style casts were carefully defined so that this assertion is
"sharp":  If you want to cast away constness, you *must* use const_cast.
[I'm ignoring old-style casts; obviously, they can accomplish the same
thing.]

Except ... that under the Standard, not only can't I be guaranteed that
the assertion is true; even *testing* the assertion may result in
undefined behavior, since *t may have been deleted.

The issue isn't just with delete.  If f() can invoke ~T, the assertion
also may no longer be true; and depending on the form of the assertion,
testing it may have undefined results.  (f() could go ahead after
invoking ~T to use placement new to replace *t with a T of its own
creation, with any value for t->x that it likes.  Fortunately, however,
placement new needs a void* - so at some point, the constness has to be
cast away.)

It's not hard to write down the conditions on f() under which the
assertion is supportable.  Most of them are intuitive (the condition can
only depend on the logical interface of f(), T is properly programmed so
that its logical interface doesn't depend on any mutable elements, no
const_cast's.  Note that mutable was added to C++ exactly to make the
most common uses of const_cast's superfluous).  These are the kinds of
things you'd expect to check *anyway*.  Under the Standard, you must
also check that the additional conditions that f() doesn't delete or
call the destructor on its argument.  I suppose some might find that
intuitive; I don't.  This is exactly the kind of thing I'd like the
compiler to check *for* me.  When I want to get around the limitation,
I'll say so explicitly - that's exactly what const_cast is for.

| If 'const'ness implies undestructibility, then const autos should be
| classified ill-formed, for the sake of consistency.

Pardon me, but that reminds me of the statement that some assertions are
so foolish that only a intellectual could believe them.  Why not argue
that, "for consistency", constructor's shouldn't be allowed to
initialize const members?  Or that functions calls shouldn't be allowed
to initialize const formals?  After all, const says "doesn't change"; it
doesn't say "changes only once".  So are you ready to eliminate const
from the language entirely?
       -- Jerry
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/30
Raw View
ncm@nospam.cantrip.org (Nathan Myers) wrote:
> The issue (trying to be) under discussion is how such arguments can
> seem persuasive to intelligent people.

Actually, you're the only person who seems to want to discuss this. Do you
have any insights you want to share? You seem to have given it more
thought than anyone else.

For what it's worth, the issue reminds me a little of Plauger's
meta-discussion of malloc(0), in his book "Programming On Purpose II".
Much of the base discussion revolved around two arguments, labelled by
Plauger:

    16+ Zero should behave like any other number.
    16- Zero is a special case, different from any number.

To me, the idea that "delete p" changes *p and so should be forbidden if
*p is const, is so obvious that it takes real mental effort to explain
why. But for other people, the opposite is apparently equally opposite and
they too have trouble explaining why.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1999/09/30
Raw View
Francis Glassborow wrote:
>
> In article <37F17C03.CBEA241F@cs.tu-berlin.de>, Roman Lechtchinsky
> <wolfro@cs.tu-berlin.de> writes
> >The discussion has been about const pointers, though, and not about
> >const objects. I'd expect a function which has a "T const *p" parameter
> >to guarantee that, aliasing issues aside, the object p points to doesn't
> >change. This implies that p still points to an object when the function
> >returns, IMHO. What guarantee does this function provide under the new
> >rule?
>
> I think you are confusing pointer to const object with const pointer to
> object.  I agree that in the later case the pointer should continue to
> point to the same object but that was not the issue this thread was
> about.

No, I probably just didn't make my point clear. Under the old rule,
given the function

  void f(T const *p);

and the usual semantics of copying and comparison for type T, you could
assume and have the compiler check that c is true in the following code
as long as one doesn't use casts.

  x = *p;
  f(p);
  c = x==*p;

This doesn't hold anymore. In fact, this exhibits a small logical
mistake in the argument that it's ok to delete the object p points to
because it doesn't change the object's state, IMO. Lets assume that f
deletes the object p points to and that deleting an object doesn't
change it. If one wanted to do formal logic, the statement "the call to
f didn't change the object p points to" wouldn't be true because p
doesn't point to an object when f returns. The only thing one could say
would be "the call to f didn't change the object p pointed to before the
call" but this doesn't really make sense to me. I just wanted to point
out this subtle difference.

> >Anyway, all arguments in favor of deleting const pointers I've seen so
> >far have been either very technical or somewhat philosophical. What
> >about software engineering? IMO deleting const pointers is generally a
> >bad idea when implementing OO designs.
>
> Of course it is, so is deleting any object via a pointer passed as an
> argument.

Yes, but I'd still like to know what impact this change has on software
engineering. Does it change the way people write programs? Are there
more bugs because of it?

Bye

Roman


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/09/30
Raw View
Jerry Leichter <jerrold.leichter@smarts.com> writes:

| | >Const determines which of a set of specific operations are permitted.
| | >Changing the (sub)set of permitted operations changes const's
| | >usefulness as a language primitive.
| |=20
| | In that case how can a destructor ever be applied to a const auto or
| | static object?
|
| This topic has been discussed before - on reason this discussion goes on
| forever is that its history is repeatedly erased.
|
| Your question actually has two real questions underlying it:
|
| 1.  If I write:
|
|  { const T t;
|   ...
|  }
|
| how would t ever get destroyed (destructed and its memory released) if
| delete can't be applied to a const object?  (The question for statics is
| identical.)

Whereas there have been lengthy postings on this issue, I still fail
to see why const should imply /undestructible/.

If 'const'ness implies undestructibility, then const autos should be
classified ill-formed, for the sake of consistency.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/09/30
Raw View
In article <37f1f020$0$219@nntp1.ba.best.com>,
Nathan Myers <ncm@nospam.cantrip.org> wrote:

>I'm not moaning over the change, mistake or no.  I'm interested
>in how logically-invalid arguments came to be considered persuasive.
>I'd like to learn how to recognize when it is likely to happen
>again.

I believe that this discussion is a good example of what Ayn Rand calls
an ``argument from intimidation.''  She described it in the Objectivist
Newsletter, Volume 3, no. 7, in July 1964.  It would be inappropriate
for me to quote the entire article, but a few short quotes should
give enough of an idea:

 There is a certain type of argument which, in fact, is not
 an argument, but a means of forestalling debate and extorting
 an opponent's agreement with one's undiscussed notions.
 It is a method of by-passing logic by means of psychological
 pressure.

 ...

 This method bears a certain resemblence to the fallacy
 ``ad hominem,'' and comes from the same psychological root,
 but is different... The ``ad hominem'' fallacy consists of
 attempting to refute an argument by impeaching the character
 of its proponent.  Example:  ``Candidate X is immoral, therefore
 his argument is false.''

 But the psychological pressure method consists of threatening
 to impeach an opponent's character by means of his argument,
 thus impeaching the argument without debate.  Example:
 ``Only the immoral can fail to see that Candidate X's
 argument is false.''

Nathan Myers' continued insistence that any arguments with which he
disagrees are ``logically invalid'' is a sterling example of this technique.
Its continued use prevents all possibility of rational discussion,
so there is no point in continuing to try.  All that can possibly result
is a restating of the same positions, at successively higher volume,
with no true insight or understanding.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/30
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>Nathan Myers <ncm@nospam.cantrip.org> wrote:
>
>>>2. Const has not been broken, according to the definition that you gave
>>>   in an earlier post.  That is, there is no code that used to work that
>>>   now fails.
>
>>Const has been broken because its semantics changed and anything that
>>depended on those old semantics is broken.   That code appears to run
>>correctly is only one measure of correctness -- as Andrew is certainly
>>aware.
>
>So you're objecting to your own earlier definition?

No.  Read carefully:  "anything that depended on those old semantics
is broken".  I'm dead certain that Andrew is capable of discovering
examples of that for this case, if he cares to.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/30
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>Jerry Leichter  <jerrold.leichter@smarts.com> wrote:
>
>>Objecting to a change in C++ because it requires the programmer to write
>>additional code is like objecting to the sun rising.
>
>Sarcasm is not a good way to contribute to a technical discussion.

Nor is ignoring the entire substantive portion of an exceptionally
clear and well-stated posting and replying only to a fragment of
levity contained there.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/30
Raw View
In article <37f30bc1$0$222@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>>Suppose we have:
>>
>>   delete p; // p is a pointer to a const T
>>
>>The compiler "magically" transforms this into:
>>
>>  p->~T(); // (1)
>>  release-memory( p ); // (2)
>>
>>(2) is legal, trivially.
>>
>>(1) is legal, because:
>
>Here we have "Exhibit A" again, restated in excruciatingly erroneous
>detail.

You keep saying that.  ~T() is a non const member function that can be
called on a const object because the standard so stipulates.  delete is
a keyword that can be applied to the address of a dynamically created
object (even if const) because the Standard says so.

The Standard could have said otherwise.  In the opinion of many that was
a judgement call.  I think that arguments based on the defined behaviour
of delete are reasonable and defensible though not absolute.  Your
characterisation says otherwise and seems to me to be the basis on which
you believe that those who voted for the change were doing so based on
fallacious arguments.

I do not think we can make any further progress on this issue.

>From the perspective of programmers, they should be taught that they
should never apply delete to a pointer unless they know that the pointer
'owns' the object pointed to.  That is best done by some form of smart
pointer.

I have frequently argued that the appearance of delete in client code is
always suspect, and like a cast should always be justified and
commented.

>
>
>"delete p" is not the same as "p->T::~T(); operator delete(p);".
>"delete p" is a first-class statement in its own right.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <jerrold.leichter@smarts.com>
Date: 1999/09/30
Raw View
| >Const determines which of a set of specific operations are permitted.
| >Changing the (sub)set of permitted operations changes const's
| >usefulness as a language primitive.
|=20
| In that case how can a destructor ever be applied to a const auto or
| static object?

This topic has been discussed before - on reason this discussion goes on
forever is that its history is repeatedly erased.

Your question actually has two real questions underlying it:

1.  If I write:

 { const T t;
  ...
 }

how would t ever get destroyed (destructed and its memory released) if
delete can't be applied to a const object?  (The question for statics is
identical.)

Now, first of all, delete is never called here anyway.  But let's ignore
that, since clearly the ARM was inconsistent:  If it's illegal to call
delete on a const pointer, it should be illegal to invoke the destructor
on it, for exactly the same reasons.  Suppose that were true.  Even so,
*no one ever said the operation of compiler-generated code could be
expressed in legal C++*.  There is no C++ call that allocates or
releases stack space; nevertheless, *somehow* the generated code for
this block does so.  That never seemed to bother anyone before.  Why
should it bother anyone that the compiler somehow manages to invoke t's
destructor?  (In any case, in this case the operation *is* readily
expressible in C++ code:  The compiler casts &t to a non-const version
and invokes the destructor on that.)

2.  So, what if I write:

 { const T t;
  ...
  t.~T();
  ...
 }

In fact, *this code cannot be part of a correct C++ program*.  Before
we reach the end of the block, we must use placement new to construct a
valid object in t.  From the Standard, Section 3.8:

 8 If a program ends the lifetime of an object of type T with  =09
 static (3.7.1) or automatic (3.7.2) storage duration and if T=20
 has a non=ADtrivial destructor,35) the program must ensure that an=20
 object of the original type occupies that same storage location=20
 when the implicit destructor call takes place; otherwise the=20
 behavior of the program is undefined. This is true even if the=20
 block is exited with an exception. [Example:
 class T { }; struct B { ~B(); };
 void h() { B b; new (&b) T; } //undefined behavior at block exit=20
 =D0end example]

However, just after this text, we read:

 9 Creating a new object at the storage location that a const=20
 object with static or automatic storage duration occupies or, at=20
 the storage location that such a const object used to occupy=20
 before its lifetime ended results in undefined behavior.=20
 [Example:
 struct B { B(); ~B(); };
 const B b;
 void h() { b.~B(); new (&b) const B; // undefined behavior }=20
 =D0end example]

       -- Jerry
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jeff Rife <wevsr@nabs.net>
Date: 1999/09/29
Raw View
Francis Glassborow (francis@robinton.demon.co.uk) wrote:

> But there is a perfectly standard idiom to ensure that a type is always
> dynamic (well strictly speaking when a client of the class creates it).
> Just have only private ctors and us a public factory function.

This is not true at all.  The factory could look like:

static int nCountOfT = 0;
static T Array[1000];

T const *FactoryForT()
{
return &Array[nCountOfT++];
}

I know I dropped error checking, etc., but the point is that the object
is *not* dynamic.

A real-world example of this might be sockets, or file handles, where
there is a per-process limit.

--
Jeff Rife                   | "Having your book turned into a movie is like
19445 Saint Johnsbury Lane  |  seeing your ox turned into bouillon cubes."
Germantown, MD  20876-1610  |
Home: 301-916-8131          |              -- John Le Carr
Work: 301-770-5800 Ext 5335 |


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/09/30
Raw View
In article <newscache$mxetif$tuh$1@firewall.thermoteknix.co.uk>,
Ken Hagan <K.Hagan@thermoteknix.co.uk> wrote:

>Andrew Koenig wrote in message ...
>>In order to claim that const has been broken, according to Nathan's
>>definition of `broken,' you have to exhibit a complete program
>>that used to work and now fails.  An isolated fragment isn't enough.

>Ah, I see. I do worry about maintenance though.

>Also, if ISO had said "'define const /**/", then are you arguing that
>because no existing code is broken that wouldn't have broken const?

Not at all, because then existing code *would* be broken.
For example:

 void f(int*) { }

 void f(const int*) { }

If const means /**/, then this example is a duplicate definition.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/30
Raw View
In article <MPG.125c4135994f19998970e@news.nabs.net>, Jeff Rife
<wevsr@nabs.net> writes
>
>Francis Glassborow (francis@robinton.demon.co.uk) wrote:
>
>> But there is a perfectly standard idiom to ensure that a type is always
>> dynamic (well strictly speaking when a client of the class creates it).
>> Just have only private ctors and us a public factory function.
>
>This is not true at all.  The factory could look like:

As the class designer it is up to you, though in the case of your
example I would also have a private dtor exactly because any attempt to
delete an instance would be an error.

>
>static int nCountOfT = 0;
>static T Array[1000];
>
>T const *FactoryForT()
>{
>return &Array[nCountOfT++];
>}
>
>I know I dropped error checking, etc., but the point is that the object
>is *not* dynamic.
>
>A real-world example of this might be sockets, or file handles, where
>there is a per-process limit.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/30
Raw View
In article <37F17C03.CBEA241F@cs.tu-berlin.de>, Roman Lechtchinsky
<wolfro@cs.tu-berlin.de> writes
>The discussion has been about const pointers, though, and not about
>const objects. I'd expect a function which has a "T const *p" parameter
>to guarantee that, aliasing issues aside, the object p points to doesn't
>change. This implies that p still points to an object when the function
>returns, IMHO. What guarantee does this function provide under the new
>rule?

I think you are confusing pointer to const object with const pointer to
object.  I agree that in the later case the pointer should continue to
point to the same object but that was not the issue this thread was
about.

>
>Anyway, all arguments in favor of deleting const pointers I've seen so
>far have been either very technical or somewhat philosophical. What
>about software engineering? IMO deleting const pointers is generally a
>bad idea when implementing OO designs.

Of course it is, so is deleting any object via a pointer passed as an
argument.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/30
Raw View
In article <37f1ea04$0$201@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>Const determines which of a set of specific operations are permitted.
>Changing the (sub)set of permitted operations changes const's
>usefulness as a language primitive.

In that case how can a destructor ever be applied to a const auto or
static object?

delete would seem to be a red-herring, because it is the fact that dtors
are always non-const members that we have to tackle.  If I understand
correctly, your view of const simply says that a const qualified object
can only have const members called on it.  In the case of the dtor this
is manifestly untrue.

Unless you can explain how const auto and const static objects can have
a non-const member (dtor) called on them I think any further discussion
is vacuous.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jeff Rife <wevsr@nabs.net>
Date: 1999/09/30
Raw View
Nathan Myers (ncm@nospam.cantrip.org) wrote:

> I should explain further.  A key use for "old const" was in cases
> much like:
>
>   T const* f() {
>     static T t;
>     return &t;
>   }
>
> The point of const here is not to indicate who should delete it,
> it is to indicate that the client should *never* delete it, and
> further, if it's deleted accidentally (or assigned through) the
> compiler should forbid it.

Right.  And my statement later in this post agrees with you, but not
about the const part.

Basically, if you can't delete const pointers, then a library can't
return an object to you that you can't modify, yet must clean up (which
happens in some systems with limited resources, especially for long-running
programs).

As I say below, the only real way to know if it is safe to delete is to
read the library specs.

> >Now, if it was more like...
> >
> >SocketStatus const* FactoryForSocketStatus(const Socket &sock)
> >  { return new const SocketStatus(sock); }
> >
> >we have an inkling of the reason for the design.
>
> What mean-um "we"?  I would find code like either of your last
> two examples entirely mystifying, I'm afraid.

What I meant was that instead of a generic type T, if we were dealing with
something a little more well known, things might be easier to understand.
In this example, it is common for things like sockets and files to have
a "status" object that is related to it, but only at some exact point in
time.  Making it const guarantees that the user can't change the values,
and lie to something that requires a SocketStatus.  Making it dynamic
means we don't have to drag it around unless the user needs it.  Possible
the SocketStatus has very descriptive text, while the Socket has only
status bits.

> With older compilers, I get a compile-time error message.

Only because of the const, *not* because of the fact that you can't *ever*
delete this structure.  There are times, however, where you must return
a non-const.  With older compilers you get undefined behavior if you tried
to delete it, but no warning.  A non-astute programmer could infer that
non-const == safe to delete, which is *never* true.

> Your mistake, here, is the same as Andrew's.  The lack of a const
> never told you anything, but the presence of a const was a clear
> message: don't delete.

Not necessarily.  It might have told me "don't change, but the stupid
compiler won't let you delete it, either, so live with the it".

With the old const meaning, systems had to be designed so that anything
logically const that was handed out dynamically (using new) was *not* a
limited resource, because long-running programs (daemons, etc.) would
eventually eat them all up, as they could not free them.

On the reverse, anything that a system wanted to allow to be deleted must
be non-const, and thus *must* be in memory that is writable by the program
that uses it.  Otherwise, you have the reverse problem, where the docs
must say "don't write to this, but it is safe to delete it".  This is
*exactly* the same situation as "don't delete this, but it is safe to
write to it".  Both are declared the same way in ARM-compliant compilers.

No matter what you make const mean on the compiler, it always comes down
to RTFM to see what you truly can do with any pointer returned from a
library you don't control.

--
Jeff Rife                   | "I'll be back in five or six days."
19445 Saint Johnsbury Lane  |
Germantown, MD  20876-1610  | "No, you'll be back in five or six pieces."
Home: 301-916-8131          |              -- "The Lost World"
Work: 301-770-5800 Ext 5335 |
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/30
Raw View
Jeff Rife <wevsr@nabs.net> wrote:
| If you can't delete it, and can't change it, what use is that T?

The mention of objects that "you can't delete" can only distract.
There are no such objects under discussion.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/30
Raw View
Ziv Caspi <zivca@netvision.net.il> wrote:
>>Nathan Myers wrote:
>[...]
>>> For example, one keeps surfacing about how it is meaningless to talk
>>> about changing an object that no longer exists.  Here's a timeline:
>>>
>>>    <---===+++++++++++++++++++========--------->
>>>        ^  ^               ^ ^       ^
>>>        V  W               X Y       Z
>>>
>>> It illustrates the lifetime of an object.  At time V, we execute a
>>> new-expression.  The constructor returns at time W.  At time Y, we
>>> execute a delete-expression, and the destructor is called.  After
>>> that point (to the right) the object doesn't exist.  The destructor
>>> runs until Z, at which point operator delete() is called.
>[...]
>>> You cannot logically say the object "no longer exists" when we are
>>> talking about whether to allow the delete-expression to be run.
>>> To me the above is elementary.
>
>Suppose we have:
>
>   delete p; // p is a pointer to a const T
>
>The compiler "magically" transforms this into:
>
>  p->~T(); // (1)
>  release-memory( p ); // (2)
>
>(2) is legal, trivially.
>
>(1) is legal, because:

Here we have "Exhibit A" again, restated in excruciatingly erroneous
detail.

"delete p" is not the same as "p->T::~T(); operator delete(p);".
"delete p" is a first-class statement in its own right.  Only if it
is legal to execute it can we look at what sub-operations it might
invoke.  Thus, the legality of (1) is irrelevant, because we haven't
even got there yet.  Furthermore, operator delete takes a non-const
void* argument, so (2) is far from "trivially" legal (not that it
matters).

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/28
Raw View
On 27 Sep 1999 20:11:39 GMT, Dave Harris <scorp@btinternet.com> wrote:

>As far as I can tell, the advantage is that heap-allocated objects become
>as easy to use as other kinds.
>
>For example, people would like to be able to take code like:
>
>    struct S {
>        T t;
>    };
>
>and rewrite it as:
>
>    struct S {
>        T *t;
>    };
>
>by adding suitable new and delete expressions. The difference would
>ideally be an implementation detail not affected by the choice of T.
>However, with the ARM rule the code *is* affected by whether T is const.

I showed that it is not that easy, even for the common case of
std::container.  The issue is that the author of template class S<T> may
have written the class with the assumption that T is a non-const value
type.  For example, class std::deque<T> uses the class std::allocator<T>,
and this class defines overloaded member functions
"pointer address(reference)" and "const_pointer address(const_reference)".
For T=="const int", these are both the same function, and this violates
the one declaration rule.



>For ordinary classes, where the type of T is known, it is a minor matter
>(IMHO), because if T is const suitable circumventions could be made at the
>time. When S is a template it is more significant. The problem is that the
>S may be written and used by different people. The person who wrote S may
>not anticipate the const T parameter, and the person who supplies the
>parameter may not be allowed to rewrite S.

This is not convincing.  If the author of class S<T> wanted T to be a
const value type, then he/she could have always used the tool to remove
the top level const.  Yes, it is a little more typing, but so what?

   template <class T>
   S<T>::~S() {
      typedef typename no_toplevel_const<T>::result uT;
      delete const_cast<uT>(this->something);
   }



>Some argue that this advantage is small. That would be a judgement call.
>Other people's judgements may differ, perhaps because they have been
>bitten by these issues in the past. It's not a matter of logic or
>intelligence, but of experience; and reasonable men with differing
>experience can reasonably differ.

If we had the rule that delete pointer to const is illegal, then at
some inconvenience, we use the above idea to still delete a pointer
to const.  But if we have the rule that delete pointer to const is
legal, then how can users enforce the rule?

The principle I'm getting at is: if we choose feature A then items
a and b are possible; if we choose feature B then only item a is
possible.  So we should choose that feature that allows most items,
or feature A.  In effect, we've given programmers more choices.
There are other examples of this principle at work in the C++
language, but I can't think of them right now.



>Secondly, in practice people don't delete const pointers anyway, even
>though C++ now allows them to. As far as I know, changing the rule has not
>produced a single known bug in the wild.

With the coding guideline that we use smart pointers as much as possible
in our code, we hardly ever have to use "delete", and so the problem goes
away.  Not too bad :).

--
--------------
siemel b naran
--------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 1999/09/28
Raw View
Andrew Koenig wrote in message ...
>2. Const has not been broken, according to the definition that you gave
>   in an earlier post.  That is, there is no code that used to work that
>   now fails.


    void DoSomething(T const*);
    Thing* t = new Thing;
    DoSomething(t);
    delete t;

This code used to work. It now crashes.

If you'd wanted to provoke a crash before, you'd have had to use
const_cast. Now you don't. In that sense, the guarantees offered
by "const" have been lost.

Having read your long (13:Sep) posting, I now recognise that there
is an issue here, and that reasonable people can say "but const
never meant that". However, many of us thought it did, and wrote
code which is no longer safe. So, there *is* code that used to work
that now fails.



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/28
Raw View
Dave Harris <brangdon@cix.co.uk> wrote:
>
>When S is a template it is more significant. The problem is that the
>S may be written and used by different people. The person who wrote S may
>not anticipate the const T parameter, and the person who supplies the
>parameter may not be allowed to rewrite S.
>
>Thus the ARM rule created a burden of prescience. The author of S must
>have foresight about how S will be used. The standard reduced the need for
>prescience.
>
>Some argue that this advantage is small. That would be a judgement call.

The size of the advantage is not the only issue.  Any such advantage
is necessarily very uneven.  If the author of S just happened to apply
only deletion and copy construction, the user of S might have the happy
experience of finding that S<const T> works, by accident.  If the author
of S just happens to have used assignment, then the user gains no
advantage.  If S gets changed later to use assignment, the user's code
breaks.  (In practice, few coders avoid assignment without reason, so
in practice the happy accident is rare.)

The magnitude of advantages for the alternatives is necessarily moot,
regardless of any arguments we may present; the standard is out.

However, the value of the arguments themselves, as presented, has been
interestingly one-sided.  The heavy use of objectively-invalid argument
forms, mostly confined to a single issue, is necessarily interesting.
Why are those invalid argument forms used here not respected (or used,
much) in other topic areas in this same forum?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Christopher Eltschka <celtschk@physik.tu-muenchen.de>
Date: 1999/09/28
Raw View
Francis Glassborow wrote:

[...]

> My intention was that we should provide a mechanism for qualifying
> pointers at top level, nothing more (OK this will require thought when
> we get to multiple levels of indirection)
>
> I now wonder if top level const qualification on a pointer should do
> what I want.  It is quite clear that delete applied to a pointer changes
> the pointer (its value moves from determinate to undetermined).  The
> pointer variable still exists but has changed.

It wouldn't:

void foo(int* const p);
{
  // delete p; would be illegal, but:
  int* p2=p; // copying const into non-const is allowed
  delete p2;
}


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/28
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>Siemel B. Naran <sbnaran@uiuc.edu> writes
>>The reasons in favor of the new behavior (namely that delete pointer to
>>const is ok) seem to draw out the logicality of the behavior.  And
>>perhaps the new behavior is more logical.  However, a little illogic
>>doesn't hurt.  At least the old somewhat illogical rule adds some
>>safety in the class of problems where we pass a pointer to const: we
>>are sure that no-one can delete the pointer.
>
>I see, we should have retained the ARM position not because it is right
>but because it is safely wrong <g> Wow! Nathan is just going to love
>that <  g  >

Perhaps Siemel is just demonstrating, coyly, that a nonsensical argument
can be entered on either side of the issue.  Such arguments don't mean
anything toward the outcome, but their heavy presence on either side
indicates the same thing: there's something about this issue that seems
to invite nonsensical arguments, and we must be on our guard.

But what _is_ it about this issue, particularly, that brings out such
riches of nonsense argument?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jeff Rife <wevsr@nabs.net>
Date: 1999/09/28
Raw View
Nathan Myers (ncm@best.com) wrote:

> >OK, now, let's bring a function into play, because formal parameters to
> >functions are the crux of this argument.
>
> Correct.  (Though, pointers returned from functions are involved too.)

Right.  I was trying to avoid some of the examples of:

// If we change the rules, I can't do the following:
void foo()
{
T const *pT = new const T();
delete pT;
}

To which I would respond, then don't use const there.  You didn't want
or need it, so don't use it.

To me, this example has nothing to do with true const, yet variations on
it have been presented quite a few times here.

> >Thus, it turns out that by allowing deletion through a const pointer,
> >and actually allowing the creation of a const object through new, the
> >ISO/ANSI standard is somewhat safer, because the const_cast could
> >*always* do the delete for ARM code.
>
> Not correct.
>
> The presentation above is exceptionally clear and accurate, right up
> until the last paragraph.

Even with your argument about the last paragraph, thanks for the
compliment, Nathan.

> But ... a language that makes it easier to code undefined behavior
> accidentally cannot reasonably be called safer.  A cast is a red
> warning that somebody had better prove the operation it enables is
> valid.  Being able to do the same thing without a cast is certainly
> more convenient, but it is anything but safer.

Well, I see your point, but it hinges on a crux assumption we both made,
namely my bit about:

> >(Let us assume that pT points to an object that was allocated with new,
> >because, if not, all bets are off, because that invokes undefined
> >behavior, no matter what.)

You see, what I was trying to say was that I can *never* see a reason
for a function in a library like...

void foo(T const *pT)
{
delete pT;  // Use whatever cast you need to actually do the job
}

...to be coded.  This is horrible code, as it relies on that assumption
that the object was created on the heap, and there is *no way* to know
this.  At least the ISO/ANSI standard has made even deleting from the
heap harder.  To be honest, even if pT was declared to be T *pT, then the
function is a terrible thing, in a generic library.

Now, since you mentioned function return values, let's look at::

void *realloc(void *memblock, size_t size);

For ISO/ANSI C++, this *should* be declared as...

void *realloc(void const *memblock, size_t size);

...to let us know that it won't change the bits associated with memblock,
but that it can move it and then free it.  How would you handle this
sort of thing with no deletion of const objects?  I know it isn't using
delete, but I actually couldn't come up with an example, which is
another reason I don't think things are too broken.

As for something like:

T const *ConstFactoryForT()
{
return new const T();
}

If you can't delete it, and can't change it, what use is that T?  I sumbit
that it is the same as my example at the top of this post.  Why did the
class designer require the factory method for this?  I'd seriously think
about using that sort of library.

Now, if it was more like...

SocketStatus const *FactoryForSocketStatus(const Socket &sock)
{
return new const SocketStatus(sock);
}

we have an inkling of the reason for the design.  But, I sumbit that if
the library says "don't delete this", then you need to follow that, instead
of looking at const, because they could have done:

SocketStatus ss[255];
SocketStatus const *FactoryForSocketStatus(const Socket &sock)
{
return const_cast<SocketStatus const *>(&ss[sock.number]);
}

Hey, delete it now, and see what happens.

So, I submit that under any form of "const" (ARM, ISO/ANSI, or even the
broken MSVC implementation :), you can't rely on that to know whether it
is safe to delete, thus deleting through an unknown pointer is evil, and
you should never do it.  If you find out a library does this without
telling you, complain to the library creator.

--
Jeff Rife                   | Coach: What would you say to a nice beer, Normie?
19445 Saint Johnsbury Lane  |
Germantown, MD  20876-1610  |  Norm: "Going down"?
Home: 301-916-8131          |
Work: 301-770-5800 Ext 5335 |
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Markus Mauhart" <mmauhart@ping.at>
Date: 1999/09/28
Raw View
Valentin Bonnard <Bonnard.V@wanadoo.fr> wrote ..
>=20
> Francis Glassborow wrote:
>=20
> > I would strongly favour the next version of the C++ standard (or =
even
> > via a corrigendum) providing another qualifier to inhibit =
destruction.
>=20
> void foo ()
> {
>     no_destroy int i;
> } // valid ?
>=20
> Not that i _is_ destroyed.

Probably the name "no_destroy" alone is not enough description.
I would describe its intent as ..

  A 'delete expression' for a no_destroy qualified pointer is not =
allowed.
  A 'function call expression' (note: this is a 'postfix expression'), =
where
  the function is a destructor (note: this is a 'member function call'),
  is not allowed if the 'object expression' (the first expression in the
  'postfix expression') has static type of 'pointer or reference to a
  no_destroy-qualified object'.

This definition mentions some kinds of expressions that may not be part
of a wellformed program, while it does not forbid compiler generated
destructors, e.g. for subobjects (i.e. base, members and array elements)
or for automatic and static objects or during stack-unwinding.

And IMHO an ideal world's 'const' would suply such 'no_destroy'
functionality (which doesnt mean that I want to break existing code
or standards).
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/28
Raw View
On 27 Sep 1999 22:58:38 GMT, Francis Glassborow

>>The reasons in favor of the new behavior (namely that delete pointer to
>>const is ok) seem to draw out the logicality of the behavior.  And
>>perhaps the new behavior is more logical.  However, a little illogic
>>doesn't hurt.  At least the old somewhat illogical rule adds some
>>safety in the class of problems where we pass a pointer to const: we
>>are sure that no-one can delete the pointer.
>
>I see, we should have retained the ARM position not because it is right
>but because it is safely wrong <g> Wow! Nathan is just going to love
>that <  g  >

The position that you cannot delete a pointer to const is logical in
its own way -- so to call it "safely wrong" isn't entirely correct.
Maybe "safely kind-of wrong" is better.

--
--------------
siemel b naran
--------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/28
Raw View
Al Stevens <alstevens@midifitz.com> wrote:
>Nathan Myers
>>Al Stevens <alstevens@midifitz.com> wrote:
>>>Nathan Myers wrote
>>>>Now that deletion of pointer-to-const without casting away const is
>>>>legal, our need to deplore has increased.
>>>
>>>... On balance, where do you think we stand?
>>
>>  The standard is what it is.
>
>... Is the issue being discussed here representative of
>the actions of the committee and their consequences or is it not?

It seems atypical to me.  That's what makes it interesting.

>Are there other such issues about which reasonable people continue to
>disagree and, in your opinion, continue to advance unsupported arguments
>and fail to respond to arguments to the contrary?

There are plenty of areas where reasonable people (myself included)
disagree, but very few where one side favors objectively identifiable
logically-unsound arguments.  By "objectively identifiable" I mean
that someone entirely unfamiliar with C++ could recognize the
unsoundness, merely from the form of the argument.

>Is C++ overall more or less deplorable than it was before?

Than before standardization?  The language is far-and-away stronger,
more useful, and more portable.  I don't know what you mean by
"deplorable".  The term was used here earlier to describe questionable
practices, not languages.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/28
Raw View
Consider this:

Why doesn't the standard require a
  char volatile * strchr(char volatile *, char);
or a
  char const volatile* strchr(char const volatile*, char);

Logically they should be there.

In practice we don't follow through on volatile because it isn't used
very much.  And if we had to provide volatile versions of everything,
that would be a major pain.

A destructability modifier _will_ be used a lot.  And we _will_ have to
follow through on it.  Just like you can't make a program that is half
const correct and half not, a destructability modifier is all or
nothing.  Given that choice I prefer nothing.

- Anders
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/28
Raw View
In article <37ee753a$0$200@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>There must be some really compelling argument for the change that
>just hasn't surfaced yet.  To me it's really interesting that such
>weak arguments keep getting dragged out of their deathbeds and
>forced to dance before being shot down again.

Sometimes the strength of an argument is in the eye of the beholder.
Much of this thread has been tending towards very abstract philosophy.

For example:

If a const object remains unaltered until the time of its destruction,
in what way has its const'ness been violated? It was never changed.
To my perverse view objecting is like asking what existed before the
'Big Bang', meaningless.  If during the object's lifetime it was never
changed why should we care about what happens after its lifetime has
ended?  Nathan defines this as an illogical argument or terms to that
effect.  The only way that I can equate that with a logical view is if
he is maintaining that destruction changes the object and is so
prohibited.

I would be very grateful if Nathan would define his understanding of
const (preferably without referring to (im)mutability and
(non-)destructability).  He may think the answer is obvious, but it is
not obvious to me nor, I suspect, to a number of other followers of this
thread.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/28
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>Nathan Myers <ncm@nospam.cantrip.org> wrote:
>
>>The only example offered of "what we have gotten in exchange" was
>>Container<const T>, but it has been amply demonstrated that this
>>was about equally easy before the change.  Thus, the question remains
>>open.  No new utility has been demonstrated for having broken const.
>
>Two falsehoods in one statement:
>
>1. It is most definitely not ``about equally easy'' to write a container
>   that will work with T and with const T as it was before the change.

It was demonstrated so, and very concisely.  I suppose Andrew missed it;
here, again, is how you convert a regular container into one that allows
instantiation on const T.

No support for const T:

  template <class T> class Container {
    void f() { T* p = new T; delete p; }
    void g() { T* p = new T; *p = T(); }
  };

Support for const T:

  template <class T> class Container {
    template <class U> static U* unconst(U const* p)
      { return const_cast<U*>(p); }
    void f() { T* p = new T; delete unconst(p); }
    void g() { T* p = new T; *unconst(p) = T(); }
  };

The conversion is mechanical, and each place where a change is
needed is pointed out by the compiler.  The "unconst()" is needed
anyway to support assignment, which unlike const was not broken.

(I shall assume that Andrew will not claim that all useful containers
are identically those which are most easily implemented without
assignment.)

>2. Const has not been broken, according to the definition that you gave
>   in an earlier post.  That is, there is no code that used to work that
>   now fails.

Const has been broken because its semantics changed and anything that
depended on those old semantics is broken.   That code appears to run
correctly is only one measure of correctness -- as Andrew is certainly
aware.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <jerrold.leichter@smarts.com>
Date: 1999/09/28
Raw View
| >The only example offered of "what we have gotten in exchange" was
| >Container<const T>, but it has been amply demonstrated that this
| >was about equally easy before the change.  Thus, the question remains
| >open.  No new utility has been demonstrated for having broken const.
|
| Two falsehoods in one statement:
|
| 1. It is most definitely not ``about equally easy'' to write a
     container that will work with T and with const T as it was before
     the change.

Objecting to a change in C++ because it requires the programmer to write
additional code is like objecting to the sun rising.  How often is
inheritance private?  Yet the default is private.  Why is there an
"explicit" modifier rather than an "implicit" one?  Because of years of
existing practice, even though the result is more verbose and a hell of
a lot less logical than it would have to be in an ideal world.

In this case, (a) the additional code serves an actual purpose, marking
explicitly where the type system is being subverted; (b) *existing
practice was changed*, not supported.

| 2. Const has not been broken, according to the definition that you
|    gave  in an earlier post.  That is, there is no code that used to
|    work that now fails.

Making const completely advisory in *all* cases wouldn't have broken any
existing code, and it certainly would have avoided a great deal of extra
typing.  const_cast<...> indeed!  And think of all the times you have to
do *both* a const_cast *and* a static_cast, because the Committee was so
unconcerned with all the extra typing that they refused to let you
change both type and const'ness in a single operation.

And think of it - with this little change, *all the STL containers
immediately work for const T types!*  No code changes at all!

*How* did this significant improvement to the language slip past the
Committee?

       -- Jerry

(BTW, following the same reasoning, we could make private inheritance
advisory, too.  Then we could all finally stop writing ": public" all
over the place.  Perhaps a later revision of the standard could add a
"private_subclass" qualifier for those cases where you really want
"private" inheritance.)
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/28
Raw View
>    void DoSomething(T const*);
>    Thing* t = new Thing;
>    DoSomething(t);
>    delete t;
>
>This code used to work. It now crashes.


Why? Under the old rules, DoSomething was not permitted to delete t, so
unless someone changed DoSomething, nothing is broken. The point that Andrew
makes is that legacy code is not affected by the change. The change does not
break existing code, but it compromises new code that naively expects the
same protection offered by the old rule.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/28
Raw View
Nathan Myers wrote in message <37f07ded$0$211@nntp1.ba.best.com>...

[...]
>I don't know what you mean by "deplorable".  The term was used here earlier
to describe questionable
>practices, not languages.

Well, to fertilize the nit, we can say that I meant to ask, "Does C++
promote more deplorable practices now than before or fewer?" but you
answered the question even though you did not understand it. Good trick.





[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: zivca@netvision.net.il (Ziv Caspi)
Date: 1999/09/29
Raw View
On 27 Sep 99 09:40:59 GMT, Valentin Bonnard <Bonnard.V@wanadoo.fr>
wrote:

[Actually, I'm commenting on What Mr. Myers said:]

>Nathan Myers wrote:

[...]
>> For example, one keeps surfacing about how it is meaningless to talk
>> about changing an object that no longer exists.  Here's a timeline:
>>
>>    <---===+++++++++++++++++++========--------->
>>        ^  ^               ^ ^       ^
>>        V  W               X Y       Z
>>
>> It illustrates the lifetime of an object.  At time V, we execute a
>> new-expression.  The constructor returns at time W.  At time Y, we
>> execute a delete-expression, and the destructor is called.  After
>> that point (to the right) the object doesn't exist.  The destructor
>> runs until Z, at which point operator delete() is called.
[...]
>> You cannot logically say the object "no longer exists" when we are
>> talking about whether to allow the delete-expression to be run.
>> To me the above is elementary.

Suppose we have:

   delete p; // p is a pointer to a const T

The compiler "magically" transforms this into:

  p->~T(); // (1)
  release-memory( p ); // (2)

(2) is legal, trivially.

(1) is legal, because:

  A: A destructor can be called on const objects

  PROOF of A: The following code is valid.

    { const T t; }

  The destructor ~T() is called when t goes out of scope.
  (Note that T has only a single destructor, called for both
  T objects and const T objects.)

  B: Any operation that can be performed on an object can
     also be performed on the object if all you have is a
     pointer to that object, with a proper type (if the object is T,
     you need T*; if it is const T, you need T const *).

  PROOF of B:

  As far as I can tell, statement B cannot be inferred from
  the standard. This seems to be the point, doesn't it?

Personally, I strongly believe that B should be asserted as
truth by the standard. I realize that some might disagree.
I don't see, however, why anyone would claim this belief to
be absurd, useless, or lacking practicality.


---------------------------------------------
Ziv Caspi
zivca@netvision.net.il


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jonathan Thornburg <jthorn@galileo.thp.univie.ac.at>
Date: 1999/09/29
Raw View
In article <MPG.12595a65a8702b0c989709@news.nabs.net>,
Jeff Rife <wevsr@nabs.net> wrote:

| T const *ConstFactoryForT()
| {
| return new const T();
| }
|
| If you can't delete it, and can't change it, what use is that T?  I sumbit
| that it is the same as my example at the top of this post.  Why did the
| class designer require the factory method for this?  I'd seriously think
| about using that sort of library.

I'd like to argue that objects which can't be deleted and can't be
changed, may still be very useful.

 [Disclaimer: This is a side point raised by this thread.
 I'm specifically *not* expressing any opinion here on
 whether or not delete of const objects should be allowed.]

For Jeff Rife's original example, let's call the object which can't
be deleted and can't be changed, "object X".

For my first example, suppose object X is intended to be immutable
(thus the const qualifier) and to live for the whole life of the program.
Then if we (a) know this code will always be used in an environment
the OS automagically reclaims all process memory when  main()  exits
(this includes a great many OSs), and (b) know that  ~T()  doesn't do
anything else (release locks, close files, print messages, etc) except
destroy a T object, then I think it may be reasonable to never call
delete on object X.


For a somewhat more extreme (but less generally useful) example,
consider an alternate implementation of the  ConstFactoryForT()
interface:

 T const *ConstFactoryForT()
 {
 static const my_Tobj(3,1,4,1,5,9);
 return &my_Tobj;
 }

(I'm assuming here that the context is such that a single const object
make sense for the function semantics, but that the function doesn't
want to expose the data object itself, perhaps to preserve flexibility
for future changes which would make the ConstFactorForT() function
nontrivial.)


For a very extreme counterexample to "If you can't delete it,
and can't change it, what use is that T?", let's change T to one
of the built-in types, and set up our "object X" like this:

 static const char *message_format = "hello, world\n";

--
-- Jonathan Thornburg <jthorn@galileo.thp.univie.ac.at>
   http://www.thp.univie.ac.at/~jthorn/home.html
   Universitaet Wien (Vienna, Austria) / Institut fuer Theoretische Physik
    "When you find that your views match [those of] the majority, it's
     time to pause and reflect."  -- Samuel L. Clemens, a.k.a. Mark Twain


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/29
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
> Nathan Myers <ncm@nospam.cantrip.org> writes
>>There must be some really compelling argument for the change that
>>just hasn't surfaced yet.  To me it's really interesting that such
>>weak arguments keep getting dragged out of their deathbeds and
>>forced to dance before being shot down again.
>
>Sometimes the strength of an argument is in the eye of the beholder.
>Much of this thread has been tending towards very abstract philosophy.

Discussions of abstract philosophy are of little value in language
design.  Still, certain  inherently fallacious argument forms can
only mislead or distract.  When a particular issue blinds us to the
presence of such forms, we can be led away from sound language design.


>For example:
>
>If a const object remains unaltered until the time of its destruction,
>in what way has its const'ness been violated? It was never changed.
>To my perverse view objecting is like asking what existed before the
>'Big Bang', meaningless.

I agree that it is a meaningless question, so I see no reason to
address it.

Q: How can a dead man object to having been shot?  A: He can't.
Does this make it OK to shoot people?  (Think before you act!)


>If during the object's lifetime it was never
>changed why should we care about what happens after its lifetime has
>ended?

We are not discussing "what happens after its lifetime has ended".
As has been explained many, many times, we are discussing events
_before_ its lifetime has ended -- specifically those that may
(or may not) lead up to that end.

>Nathan defines this as an illogical argument or terms to that
>effect.  The only way that I can equate that with a logical view
>is if he is maintaining that destruction changes the object and
>is so prohibited.

Francis, you are ascribing your own limitations to me.  I am under
no delusion that const has anything to do with "changing the object",
or about "immutability" or any other imponderable.


>I would be very grateful if Nathan would define his understanding of
>const (preferably without referring to (im)mutability and
>(non-)destructability).  He may think the answer is obvious, but it is
>not obvious to me nor, I suspect, to a number of other followers of this
>thread.

Const determines which of a set of specific operations are permitted.
Changing the (sub)set of permitted operations changes const's
usefulness as a language primitive.

I never suggested the above was obvious, but there can be no
questioning its factuality.  There is room for sensible disagreement
in how such changes actually affect const's usefulness.  Such
disagreement has already been expressed among those who understood
the previous paragraph.

If you want to discuss definitions of immutability, please leave
me out of it, or I am likely to overstress the moderators.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/29
Raw View
In article <MPG.12595a65a8702b0c989709@news.nabs.net>, Jeff Rife
<wevsr@nabs.net> writes
>So, I submit that under any form of "const" (ARM, ISO/ANSI, or even the
>broken MSVC implementation :), you can't rely on that to know whether it
>is safe to delete, thus deleting through an unknown pointer is evil, and
>you should never do it.  If you find out a library does this without
>telling you, complain to the library creator.

But there is a perfectly standard idiom to ensure that a type is always
dynamic (well strictly speaking when a client of the class creates it).
Just have only private ctors and us a public factory function.



Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/29
Raw View
Valentin Bonnard  <Bonnard.V@wanadoo.fr> wrote:
>Nathan Myers wrote:
>> Dave Harris <brangdon@cix.co.uk> wrote:
>> >francis@robinton.demon.co.uk (Francis Glassborow) wrote:
>> >> Finally, note that Nathan's puzzlement (about the Committees'
>> >> decision) is, IMO, rooted in his belief that the decision is
>> >> fundamentally flawed.

[note: I have already objected to the blatantly false statement above.]

>> >I agree with you that it's premature to discuss why people made a
>> >mistake before there is a consensus that they did, in fact, make
>> >a mistake.
>>
>> The discussion is not about a (putative) mistake.  Although I happen
>> to think they did make a mistake, that's not the point; the change
>> was made, and we have to live with it.  The discussion is about the
>> invalid arguments that were presented in support of the change, and
>> the others that have since surfaced, and are still (!) being repeated.
>
>Non-sensical arguments have been used on both sides
>of the discussion. It happens all the time. That doesn't
>mean anything about which choice is better.

Valentin, didn't you read the paragraph you replied to?
I just said that!  Still, it doesn't happen "all the time".
It wouldn't be so interesting if it did.


>> For example, one keeps surfacing about how it is meaningless to talk
>> about changing an object that no longer exists.  Here's a timeline:
>>
>>    <---===+++++++++++++++++++========--------->
>>        ^  ^               ^ ^       ^
>>        V  W               X Y       Z
>>
>> It illustrates the lifetime of an object.  At time V, we execute a
>> new-expression.  The constructor returns at time W.  At time Y, we
>> execute a delete-expression, and the destructor is called.  After
>> that point (to the right) the object doesn't exist.  The destructor
>> runs until Z, at which point operator delete() is called.
>
>OK
>
>> When we are about to execute a delete-expression we are clearly at
>> point X.  At point X the object clearly exists, and constness and
>> (if you like) mutability are very much an issue for objects that
>> (still) exist.
>
>Yes
>
>> You cannot logically say the object "no longer exists" when we are
>> talking about whether to allow the delete-expression to be run.
>
>As soon as you enter the delete-expression, the object isn't const
>anymore; see: ...

Valentin, didn't you read the sentence you answered?  We are talking
about *before* we enter the delete expression, not *after*.

>> To me the above is elementary.
>
>It is a *point of view*.  Which point of view is ``right'' is purely
>subjective.

I don't care about "which point of view is``right''", whatever that
means.  Logical coherence isn't a "point of view".  (What are they
teaching in school these days?)  Subjectivity is all very fine when
there are no (or random) consequences, as when academics debate
literature.  But we are building systems that must work, and muddy
thinking results in designs that work badly or not at all.

You can love a logically incoherent argument (I have!), but you do
violence to yourself when you let it affect your opinion.


>IMO, the fundamental problem here isn't that people use technically
>wrong arguments (it happens all the time). The problem is that you
>consider _your_ philosophical choice as the Right Thing.

What?


>> I am fascinated to find that not everybody thinks so, and
>> that people keep mentioning "changing an object that no longer exists".
>
>I am fascinated by your belief that you have the truth.

I have some facts.  I'd like some more.  "Truth" is beyond my ken.


>> Can anybody tell me what is so appealing about the "no longer exists"
>> argument that the appeal overcomes elementary logic?
>
>There are two possible definition of immutability: ...

Who said anything about "immutability"?  The vote was about "const".

Anyway, that answer avoids the question.  Reread it, please.
The question was how an argument that confuses the two fundamentally
distinct times X and Y could come to be taken seriously, and repeated
even after its weaknesses have been pointed out.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/29
Raw View
In article <XK6I3.278$tk3.406@news.get2net.dk>, Anders J. Munch
<andersjm@dancontrol.dk> writes
>Why doesn't the standard require a
>  char volatile * strchr(char volatile *, char);
>or a
>  char const volatile* strchr(char const volatile*, char);
>
>Logically they should be there.

I think not.  It is not logical to search a string for a character when
that string is specified to be able to change between one look and the
next.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Roman Lechtchinsky <wolfro@cs.tu-berlin.de>
Date: 1999/09/29
Raw View
Francis Glassborow wrote:
>
> If a const object remains unaltered until the time of its destruction,
> in what way has its const'ness been violated? It was never changed.

The discussion has been about const pointers, though, and not about
const objects. I'd expect a function which has a "T const *p" parameter
to guarantee that, aliasing issues aside, the object p points to doesn't
change. This implies that p still points to an object when the function
returns, IMHO. What guarantee does this function provide under the new
rule?

Anyway, all arguments in favor of deleting const pointers I've seen so
far have been either very technical or somewhat philosophical. What
about software engineering? IMO deleting const pointers is generally a
bad idea when implementing OO designs.

Bye

Roman
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/29
Raw View
Jeff Rife  <wevsr@nabs.net> wrote:
>Nathan Myers (ncm@best.com) wrote:
>
>> >OK, now, let's bring a function into play, because formal parameters to
>> >functions are the crux of this argument.
>>
>> Correct.  (Though, pointers returned from functions are involved too.)

I should explain further.  A key use for "old const" was in cases
much like:

  T const* f() {
    static T t;
    return &t;
  }

The point of const here is not to indicate who should delete it,
it is to indicate that the client should *never* delete it, and
further, if it's deleted accidentally (or assigned through) the
compiler should forbid it.

Since the change, the compiler will catch assignments, but
not deletions, and this interface is not safe any more.

>> >Thus, it turns out that by allowing deletion through a const pointer,
>> >and actually allowing the creation of a const object through new, the
>> >ISO/ANSI standard is somewhat safer, because the const_cast could
>> >*always* do the delete for ARM code.
>>
>> Not correct.
>
>> But ... a language that makes it easier to code undefined behavior
>> accidentally cannot reasonably be called safer.  A cast is a red
>> warning that somebody had better prove the operation it enables is
>> valid.  Being able to do the same thing without a cast is certainly
>> more convenient, but it is anything but safer.
>
>Well, I see your point, but it hinges on a crux assumption we both made,
>namely my bit about:
>
>> >(Let us assume that pT points to an object that was allocated with new,
>> >because, if not, all bets are off, because that invokes undefined
>> >behavior, no matter what.)
>
>You see, what I was trying to say was that I can *never* see a reason
>for a function in a library like...
>
>void foo(T const *pT)
>{
>delete pT;  // Use whatever cast you need to actually do the job
>}
>
>...to be coded.

I would code it, but would not expose it in a public interface.

>This is horrible code, as it relies on that assumption
>that the object was created on the heap, and there is *no way* to know
>this.

There is no way for the function itself to know, but the caller may
have any of several ways to know.  It might be better for the caller
to be obliged to express that knowledge explicitly by casting before
the call -- depending on what the function's real name is.

>At least the ISO/ANSI standard has made even deleting from the
>heap harder.  To be honest, even if pT was declared to be T *pT, then
>the function is a terrible thing, in a generic library.
>
>Now, since you mentioned function return values, let's look at::
>
>  void *realloc(void *memblock, size_t size);
>
>For ISO/ANSI C++, this *should* be declared as...
>
>  void *realloc(void const *memblock, size_t size);
>
>...to let us know that it won't change the bits associated with memblock,
>but that it can move it and then free it.

I don't agree.  It destroys one object and creates another with the
same bit pattern.  Anybody who keeps a copy of the "memblock" argument
finds themselves deep in "undefined behavior" land.

>How would you handle this
>sort of thing with no deletion of const objects?

Who can say?  We always had deletion of const dynamic objects.


>As for something like:
>
>T const* ConstFactoryForT() { return new const T(); }
>
>If you can't delete it, and can't change it, what use is that T?

I don't know.  You wrote it.


>I submit that it is the same as my example at the top of this post.
>Why did the class designer require the factory method for this?
>I'd seriously think about using that sort of library.

OK, I will.

>Now, if it was more like...
>
>SocketStatus const* FactoryForSocketStatus(const Socket &sock)
>  { return new const SocketStatus(sock); }
>
>we have an inkling of the reason for the design.

What mean-um "we"?  I would find code like either of your last
two examples entirely mystifying, I'm afraid.

>But, I sumbit that if
>the library says "don't delete this", then you need to follow that,
>instead of looking at const, because they could have done:
>
>SocketStatus ss[255];
>SocketStatus const* FactoryForSocketStatus(const Socket &sock)
>{
   return ss + sock.number;
>}
>
>Hey, delete it now, and see what happens.

With older compilers, I get a compile-time error message.
With Standard compilers, I get a crash if I'm lucky.

>So, I submit that under any form of "const" (ARM, ISO/ANSI, or even the
>broken MSVC implementation :), you can't rely on that to know whether it
>is safe to delete, thus deleting through an unknown pointer is evil, and
>you should never do it.  If you find out a library does this without
>telling you, complain to the library creator.

Your mistake, here, is the same as Andrew's.  The lack of a const
never told you anything, but the presence of a const was a clear
message: don't delete.  The compiler helped by reporting any cases
where you (accidentally) ignored the message.

Now the compiler won't help you at all, so const cannot carry that
message any more.  You have to build up a class object wrapper to
carry the same information, now.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/29
Raw View
In article <37F0C9AF.7A6F@smarts.com>, Jerry Leichter
<jerrold.leichter@smarts.com> writes
>Making const completely advisory in *all* cases wouldn't have broken any
>existing code, and it certainly would have avoided a great deal of extra
>typing.  const_cast<...> indeed!  And think of all the times you have to
>do *both* a const_cast *and* a static_cast, because the Committee was so
>unconcerned with all the extra typing that they refused to let you
>change both type and const'ness in a single operation.

I do not see any smileys;-) For the record the decision about the
verbosity of casting was deliberate and conscious.  Just for once sound
engineering practice came to the fore, dangerous things should be hard
to do and highly visible when done.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/29
Raw View
sbnaran@uiuc.edu (Siemel B. Naran) wrote:
> The issue is that the author of template class S<T> may have written
> the class with the assumption that T is a non-const value type.

This is another way of saying that the advantage is small.


> If the author of class S<T> wanted T to be a const value type,
> then he/she could have always used the tool to remove the top
> level const.

This requires foresight on the part of the author of the template. In
effect it is another way of coupling client to server. Ideally we want
*generic* templates, that work for maximal ranges of parameter types
without special effort from the authors. The ARM rule was a step away from
that, albeit a small one.


> But if we have the rule that delete pointer to const is legal, then
> how can users enforce the rule?

You can write a wrapper class that acts as a pointer but which does not
allow deletion. Whichever way the rule goes, you can get the other
behaviour by writing wrapper classes. So this argument is largely about
defaults.

Admittedly, in this case the wrapper cannot expose the address of the
const object at all, so would be incompatible with existing code.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/29
Raw View
ncm@nospam.cantrip.org (Nathan Myers) wrote:
> If S gets changed later to use assignment, the user's code breaks.

Yes, I agree. This is a big issue.

Instantiating S<const T> is a bit like inheriting from a class. If the
class wasn't *designed* to be used in that way, you will probably get
problems sooner or later. Relying on coincidence, it just happening to
work, is dangerous.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/29
Raw View
In article <newscache$d3krif$ly9$1@firewall.thermoteknix.co.uk>, Ken
Hagan <K.Hagan@thermoteknix.co.uk> writes
>    void DoSomething(T const*);
>    Thing* t = new Thing;
>    DoSomething(t);
>    delete t;
>
>This code used to work.

How did it used to work?


>It now crashes.
>
>If you'd wanted to provoke a crash before, you'd have had to use
>const_cast. Now you don't. In that sense, the guarantees offered
>by "const" have been lost.

Exactly, and if you had used const_cast it would have the same effect
today.  What you are saying is something different, there is code that
used not to compile which now compiles (it used not to 'work' but now
does)

>
>Having read your long (13:Sep) posting, I now recognise that there
>is an issue here, and that reasonable people can say "but const
>never meant that". However, many of us thought it did, and wrote
>code which is no longer safe. So, there *is* code that used to work
>that now fails.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Ken Hagan" <K.Hagan@thermoteknix.co.uk>
Date: 1999/09/29
Raw View
Andrew Koenig wrote in message ...
>In order to claim that const has been broken, according to Nathan's
>definition of `broken,' you have to exhibit a complete program
>that used to work and now fails.  An isolated fragment isn't enough.


Ah, I see. I do worry about maintenance though.

Also, if ISO had said "'define const /**/", then are you arguing that
because no existing code is broken that wouldn't have broken const?




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/29
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>In order to claim that const has been broken, according to Nathan's
>definition of `broken,' you have to exhibit a complete program
>that used to work and now fails.  An isolated fragment isn't enough.

I didn't make any requirement of "complete programs" in my definition.
It is the rare program nowadays that is constructed all of a piece.
All significant programs use libraries, so all most of us ever write
are program fragments.  Andrew is fully aware of this.

A language change which results in a change to a library's "interface
guarantees" has certainly broken that library, regardless of its
effects on the complete programs already using that library.

Furthermore, as Andrew is also well-aware, appearing to produce
correct results for a finite set of tests is not sufficient to
determine whether code "works".  In this case the set of possible
tests would be the set of complete programs that could be written
using the library.  Most would use the library incorrectly, and the
change to const results in fewer of those being detected at
compile time.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/29
Raw View
Gabriel Dos_Reis  <gdosreis@korrigan.inria.fr> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) writes:
>[...]
>
>Francis mentioned in an earlier posting that perhaps we should educate
>C++ users not to use raw pointers and teach them how to use
>"higher-level" pointers.  That alternative seems -to me- to be more
>productive, in the sens that it would bring something very useful,
>than moaning over a change (mistake?) made in the past.

I'm not moaning over the change, mistake or no.  I'm interested
in how logically-invalid arguments came to be considered persuasive.
I'd like to learn how to recognize when it is likely to happen
again.

>You mentioned in another posting that with the ARM rule, a library
>writer could release a pointer-to-const in the hands of an untrusted user
>and expect him not to destroy the object pointed-to without some pain.
>
>With Standard C++'s abstract expressionism, I would say nobody should
>release a raw pointer (to const) in the nature.

I agree.  This is new.

> One should release a:
>
>template<typename T>
>class trustful_pointer_to_const {
>public:
> trustful_pointer_to_const(const T* p = 0) : pointer(t) {}
> template<typename U>
>   trustful_pointer_to_const(trustful_pointer_to_const<U> p)
>  : pointer(p) {}
> const T& operator*() const { return *pointer; }
> const T* operator->() const { return poiner; }
> // Other useful member functions...
>private:
> const T* pointer;
> // Not implemented
> operator T*() const; // or operator const T*() const
>};

I agree.  The effect of the change has been that we must now write
zillions of ugly little classes to do the work that used to be done
by the simple built-in "T const*".  In my humble opinion that's
unfortunate.

Still, it's the law of the land now.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/27
Raw View
In article <memo.19990925163349.25925C@btinternet.com>, Dave Harris
<scorp@btinternet.com> writes
>If your proposed new qualifier achieves that default, fine. That will be
>tantamount to admitting the ARM rule was right. We could have kept the ARM
>rule and still added your qualifier later.

NO we cannot.  The only alternative is to introduce a qualifier
'deletable'. The existence of billion of lines of code that rely on
passing plain pointers that could be deleted prohibits this solution
without breaking existing code.  As soon as you use a single keyword to
mean 'non-mutable, non-destructable' you have a problem unravelling when
I also want the other three logical combinations.

Oddly, referring to many of the other replies, the posters still want to
argue by analogy (with Unix delete file) and one point I was trying to
make is that there is no logical analogy but there is a comfort factor
and an expectation.  Many (most) users are initially surprised by the
fact that you can delete a file (OK, you and I know it is only a link)
in a directory for which you have read-only access permission).  The
logic is completely irrelevant, the issue is one of unfulfilled
expectation.



Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Valentin Bonnard <Bonnard.V@wanadoo.fr>
Date: 1999/09/27
Raw View
Nathan Myers wrote:

> Dave Harris <brangdon@cix.co.uk> wrote:
> >francis@robinton.demon.co.uk (Francis Glassborow) wrote:
> >> Finally, note that Nathan's puzzlement (about the Committees' decision)
> >> is, IMO, rooted in his belief that the decision is fundamentally flawed.
> >
> >I agree with you that it's premature to discuss why people made a mistake
> >before there is a consensus that they did, in fact, make a mistake.
>
> The discussion is not about a (putative) mistake.  Although I happen to
> think they did make a mistake, that's not the point; the change was made,
> and we have to live with it.  The discussion is about the invalid
> arguments that were presented in support of the change, and the others
> that have since surfaced, and are still (!) being repeated.

Non-sensical arguments have been used on both sides
of the discution. It happens all the time. That doesn't
mean anything about which choice is better.

> For example, one keeps surfacing about how it is meaningless to talk
> about changing an object that no longer exists.  Here's a timeline:
>
>    <---===+++++++++++++++++++========--------->
>        ^  ^               ^ ^       ^
>        V  W               X Y       Z
>
> It illustrates the lifetime of an object.  At time V, we execute a
> new-expression.  The constructor returns at time W.  At time Y, we
> execute a delete-expression, and the destructor is called.  After
> that point (to the right) the object doesn't exist.  The destructor
> runs until Z, at which point operator delete() is called.

OK

> When we are about to execute a delete-expression we are clearly at
> point X.  At point X the object clearly exists, and constness and
> mutability are very much an issue for objects that (still) exist.

Yes

> You cannot logically say the object "no longer exists" when we are
> talking about whether to allow the delete-expression to be run.

As soon as you enter the delete-expression, the object isn't const
anymore; see:

void foo() {
   const int i = 4;
//i exists
} // i doesn't exist

> To me the above is elementary.

It is a *point of view*. Which point of view is ``right'' is purely
subjective.

IMO, the fundamental problem here isn't that people use technically
wrong arguments (it happens all the time). The problem is that you
consider _your_ philosophical choice as the Right Thing.

> I am fascinated to find that not everybody thinks so, and
> that people keep mentioning "changing an object that no longer exists".

I am fascinated by your belief that you have the truth.

> Can anybody tell me what is so appealing about the "no longer exists"
> argument that the appeal overcomes elementary logic?

There are two possible definition of immutability:

(1) the object shall not be touched in a way which may
    invalidate any assumptions on it

(2) the object shall not be touched in a way which may
    give it another value

Note that both appear to be quite close, until you
realize that after p->~T(), *p has no value, so calling
the destructor breaks (1) but not (2).

If you want the keyword const to mean (1), then you should
be opposed to delete (const T*)p;

If you prefer to use (2) for const, then you want
delete (const T*)p; to be valid.

Perhaps if we could write that formally it would be
clearer (anyone ?).

--

Valentin Bonnard
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@best.com (Nathan Myers)
Date: 1999/09/27
Raw View
Jeff Rife  <wevsr@nabs.net> wrote:
>Nathan Myers (ncm@nospam.cantrip.org) wrote:
>
>> In fact, the language _always_ allowed programs to delete all objects
>> they allocated.  ...
>
> So, according to the ARM, the following statements are equivalent...
>
> T const * ta = new T();
> T const * tb = new const T();
>
> ...and both are intepreted as:
>
> T const * t = new T();

Correct.

>Thus, casting away the const and deleting is OK, because the underlying
>object is *not* const.
>
>In the ISO/ANSI standard, the two lines are interpreted exactly as written,
>and are, thus, different.

Correct.

>OK, now, let's bring a function into play, because formal parameters to
>functions are the crux of this argument.

Correct.  (Though, pointers returned from functions are involved too.)

>void foo(T const *pT) { delete pT; }
>
>(Let us assume that pT points to an object that was allocated with new,
>because, if not, all bets are off, because that invokes undefined
>behavior, no matter what.)
>
>For an ARM-compliant implementation, this function fails to compile,
>but for an ISO/ANSI standard implementation, this code works, and deletes
>our object (although it might invoke undefined behavior if the underlying
>object actually *is* const), which is what people are complaining about.

Correct.

>But, let's try:
>
>void bar(T const *pT) { delete const_cast<T *>(pT); }
>
>Hey, guess what, this compiles under the ARM and doesn't invoke undefined
>behavior, because the underlying object *cannot* be const, if it was
>allocated on the heap.

Correct.

>It also compiles under ISO/ANSI, but *might* invoke undefined behavior, as
>the underlying object might actually *be* const...which is exactly the
>same as the function foo above.

Correct.

>Thus, it turns out that by allowing deletion through a const pointer,
>and actually allowing the creation of a const object through new, the
>ISO/ANSI standard is somewhat safer, because the const_cast could
>*always* do the delete for ARM code.

Not correct.

The presentation above is exceptionally clear and accurate, right up
until the last paragraph.

But ... a language that makes it easier to code undefined behavior
accidentally cannot reasonably be called safer.  A cast is a red
warning that somebody had better prove the operation it enables is
valid.  Being able to do the same thing without a cast is certainly
more convenient, but it is anything but safer.

If I dig a pit in the field and you fall in, it's my fault.  If I
post a fence around it and you jump over and fall in, it's your fault.
Is it safer with or without the fence?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/27
Raw View

Nathan Myers wrote in message <37edd7ec$0$208@nntp1.ba.best.com>...
>The resurrection of "exhibit A" here (and again below) is an example
>of the phenomenon that is the intended topic of this discussion: why
>are logically unsound arguments repeatedly advanced after they have
>been demonstrated to be unsound?


Obviously because there is not a consensus that the would-be demonstration
in fact demonstrates what it purports to demonstrate. The true phenomenon
that I find vastly more interesting is that even though all parties must
clearly see that the issue involves mutually exclusive and polarizing
arguments, with no quarter given by either side, and no points ever really
scored, the volley continues.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/27
Raw View

Nathan Myers wrote in message <37ed3037$0$210@nntp1.ba.best.com>...
>
>In article <ETXG3.18429$F07.649026@newscene.newscene.com>,
>Al Stevens <alstevens@midifitz.com> wrote:
>>
>>
>>Nathan Myers wrote in message <37ea78e5$0$219@nntp1.ba.best.com>...
>>>Now that deletion of pointer-to-const without casting away const is
>>>legal, our need to deplore has increased.
>>
>>... On balance, where do you think we stand?
>
>Who cares?  The standard is what it is.  I'm interested in exploring
>what is behind the logically-invalid arguments that keep getting posted.


I care, or I wouldn't have asked. I know what you are interested in; you
have been quite eloquent in stating that interest many times. I didn't ask
about that. Given that pre-standard C++ (ARM) had a "deplore index" and
standard C++ has a "deplore index," which way do you think that the needle
has moved and how far? Is the issue being discussed here, in your opinion as
an informed C++ practitioner and active committee member, representative of
the actions of the committee and their consequences or is it not? Are there
other such issues about which reasonable people continue to disagree and, in
your opinion, continue to advance unsupported arguments and fail to respond
to arguments to the contrary? Is C++ overall more or less deplorable than it
was before? Or the same?

This is not a frivolous question. It goes to the issue of how well the
committee paradigm works in language design as opposed to language
codification. (I don't recall any such extensive post-mortem discussions
about the C standard, although there might have been some.) Long discussions
such as these, which entail much disagreement, tend to give a distorted
picture. People will dwell on the disagreements, ignore the unmentioned
positive advances, and form impressions based on that. If you don't care to
respond, just say so.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/27
Raw View

Siemel B. Naran wrote in message ...
>I must have missed the answer.  Can you please summarize?


Not effectively, because I am among those who disagree (reasonably, I hope)
with some of the arguments in favor of the new behavior, and I wouldn't want
any such summary to unintentionally reflect my bias (or to have my mind
changed only as a function of cognitive dissonance <g>). I'll defer the
summary to someone who believes in it, or suggest that you review all the
messages yourself (which, I fear, not only deflects the work of scanning all
the messages, but shamelessly evades your question, too).




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/27
Raw View
francis@robinton.demon.co.uk (Francis Glassborow) wrote:
> 1) Today we have both const and volatile qualifications on all types yet
> how often do you see code that allows for volatile versions?  The use of
> volatile is limited in practice.

Well, yes. But the use of nodelete won't be so limited. Every heap object
will start off deletable, typically will be passed around as nodelete for
much of its life, and will be deletable again at least just before it is
deleted. I've written entire programs without using volatile but nodelete
will be very common.


> 2) Any qualification re destruction would only apply to pointers

It must also apply to references. Otherwise:

    void test1( nodelete int *p ) { test2( *p ); }
    void test2( int &i ) { test3( &i ); }
    void test3( int *p ) { delete p; }

could not be a type error, which surely defeats the object. You must also
think about:

    void test4() {
        int x = 3;
        test3( &x );
    }

It seems to me that you can't prevent this without breaking old code, and
yet if you don't prevent this you've only got a partial solution.

If your serious about it not applying to references, that's another reason
the solution is partial. I don't think the added complexity is worth it.


> As a matter of practicality, how often would I want to delete a non-
> const pointer (why would I want to change the object if I was going to
> throw it away)?  However if I intend to destroy the object it would not
> seem to make much sense to allow it to be mutated first.

Ask the opposite question. How often would I want to prevent you from
changing an object you are about to delete? Once I've handed it over to
you, I can't look at it anyway so I don't care what you do.

However, to answer your actual question, consider code that creates an
object, modifies it and then destroys it. This strikes me as very common,
and it relies on being able to delete modifiable obects.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/27
Raw View
sbnaran@uiuc.edu (Siemel B. Naran) wrote:
> >> What, precisely, are we supposed to have got in exchange?
>
> I must have missed the answer.  Can you please summarize?

As far as I can tell, the advantage is that heap-allocated objects become
as easy to use as other kinds.

For example, people would like to be able to take code like:

    struct S {
        T t;
    };

and rewrite it as:

    struct S {
        T *t;
    };

by adding suitable new and delete expressions. The difference would
ideally be an implementation detail not affected by the choice of T.
However, with the ARM rule the code *is* affected by whether T is const.

For ordinary classes, where the type of T is known, it is a minor matter
(IMHO), because if T is const suitable circumventions could be made at the
time. When S is a template it is more significant. The problem is that the
S may be written and used by different people. The person who wrote S may
not anticipate the const T parameter, and the person who supplies the
parameter may not be allowed to rewrite S.

Thus the ARM rule created a burden of prescience. The author of S must
have foresight about how S will be used. The standard reduced the need for
prescience.

Some argue that this advantage is small. That would be a judgement call.
Other people's judgements may differ, perhaps because they have been
bitten by these issues in the past. It's not a matter of logic or
intelligence, but of experience; and reasonable men with differing
experience can reasonably differ.

----
Further more, even if the benefit was small, some people argue that the
cost was also small. There are several parts to this:

Firstly, the ARM rule doesn't do the full job. Const pointers could still
be deleted (through use of casts or aliases). Nor was it always safe to
delete non-const pointers, even though the ARM allowed it. Arguably the
ARM just confused the issue and gave a false sense of control.

Secondly, in practice people don't delete const pointers anyway, even
though C++ now allows them to. As far as I know, changing the rule has not
produced a single known bug in the wild.

Thirdly, much of the cost can be mitigated by compiler warnings. The
advantage of warnings over errors is that the compiler can be as clever as
it likes about avoiding spurious complaints. For example, it can warn only
when the class that deletes the object is different to the class that
allocates it. That would catch most of the suspect cases while admitting
most of the reasonable ones. Or whatever - it becomes a quality of
implementation issue.

Again to evaluate this stuff we must use judgement calls, and reasonable
people can differ.

----
Note that I have here been playing Devil's Advocate. Personally I would
prefer the ARM rule not to have been changed. I wrote the above to see how
well I understand the opposing position. No doubt others will post
corrections.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/27
Raw View
francis@robinton.demon.co.uk (Francis Glassborow) wrote:
> > If your proposed new qualifier achieves that default, fine. That
> > will be tantamount to admitting the ARM rule was right. We could
> > have kept the ARM rule and still added your qualifier later.
>
> NO we cannot.  The only alternative is to introduce a qualifier
> 'deletable'. The existence of billion of lines of code that rely on
> passing plain pointers that could be deleted prohibits this solution
> without breaking existing code.

Well, no. We could have introduced two new qualifiers instead of one: say
"deletable" and "not_deletable", with defaults:

   const pointers are not_deletable unless explicitly declared deletable.

   Non-const pointers are deletable unless explicitly declared
       not_deletable.

That would have allowed you all 4 combinations, would be consistent with
the ARM rules and so would have broken no code, and would be reasonable
defaults for people who wanted to ignore the issue.

(This leaves the various other points I mentioned untouched. I am *not*
advocating two new keywords. My feeling is that the ARM rule shouldn't
have been changed; but now it is changed, it should be left as it is and
vendors encouraged to provide compiler warnings.)


> Oddly, referring to many of the other replies, the posters still want to
> argue by analogy (with Unix delete file) and one point I was trying to
> make is that there is no logical analogy but there is a comfort factor
> and an expectation.  Many (most) users are initially surprised by the
> fact that you can delete a file (OK, you and I know it is only a link)
> in a directory for which you have read-only access permission).  The
> logic is completely irrelevant, the issue is one of unfulfilled
> expectation.

I'm not sure what you're saying. If you mean that programmers are
surprised when they first discover that delete can be applied to a const
pointer, then I agree. It is surprising. Many of them express their
surprise in this newsgroup. In my view, a language should not surprise its
programmers unless there is compelling reason, so this is an argument for
the ARM rule.

Or maybe you are saying that Unix programmers are not surprised by C++?
Unlike you and I, they don't know it's only a link, and their
misunderstanding of Unix carries over into a misunderstanding of C++?
Again, I don't think we should have changed the ARM rule to cater for this
group. Also I don't think this accounts for the position of Mr. Koenig.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/27
Raw View
On 27 Sep 1999 16:48:53 GMT, Al Stevens <alstevens@midifitz.com> wrote:
>Siemel B. Naran wrote in message ...

>>I must have missed the answer.  Can you please summarize?
>
>Not effectively, because I am among those who disagree (reasonably, I hope)
>with some of the arguments in favor of the new behavior, and I wouldn't want
>any such summary to unintentionally reflect my bias (or to have my mind
>changed only as a function of cognitive dissonance <g>). I'll defer the
>summary to someone who believes in it, or suggest that you review all the
>messages yourself (which, I fear, not only deflects the work of scanning all
>the messages, but shamelessly evades your question, too).

The reasons in favor of the new behavior (namely that delete pointer to
const is ok) seem to draw out the logicality of the behavior.  And
perhaps the new behavior is more logical.  However, a little illogic
doesn't hurt.  At least the old somewhat illogical rule adds some
safety in the class of problems where we pass a pointer to const: we
are sure that no-one can delete the pointer.

(In Design & Evolution by Stroustrup, isn't there a sentence about
how C++ has some illogical features, but these features make it safer
to use and easier to explain?  I think I read something like this
some time ago, but I can't find the sentence any more.)

--
--------------
siemel b naran
--------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/27
Raw View
In article <slrn7uvkil.bjs.sbnaran@localhost.localdomain>, Siemel B.
Naran <sbnaran@uiuc.edu> writes
>The reasons in favor of the new behavior (namely that delete pointer to
>const is ok) seem to draw out the logicality of the behavior.  And
>perhaps the new behavior is more logical.  However, a little illogic
>doesn't hurt.  At least the old somewhat illogical rule adds some
>safety in the class of problems where we pass a pointer to const: we
>are sure that no-one can delete the pointer.

I see, we should have retained the ARM position not because it is right
but because it is safely wrong <g> Wow! Nathan is just going to love
that <  g  >

>
>(In Design & Evolution by Stroustrup, isn't there a sentence about
>how C++ has some illogical features, but these features make it safer
>to use and easier to explain?  I think I read something like this
>some time ago, but I can't find the sentence any more.)

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/09/25
Raw View
In article <199909250911.CAA20176@shell7.ba.best.com>,
Nathan Myers  <ncm@nospam.cantrip.org> wrote:

>"Now, g did not choose to make a const pointer.  Nevertheless, inside
>an instantiation of X<const int>, g will be making a const pointer
>even though it did not choose to do so."

>Any such argument you can make in favor of allowing deletion of a
>pointer-to-const applies identically to assignment.

No, it applies independently, and differently, to assignment.
There is no particular problem in defining a container that doesn't
rely on assignment for the objects it contains.  It is much harder
to define such a container for objects that don't allow deletion,
because such a container must inevitably leak memory.

>Andrew's example above has been posted many times before, and
>responses demonstrating its invalidity as well.  The criticism
>has never been acknowledged.  Why not?

Oh, but they have been acknowledged.  What I have not acknowledged
is their correctness, because they are not correct -- they are matters
of opinion, rather than objective fact.  There is an engineering
tradeoff involved -- some people like it, others don't.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/27
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>Nathan Myers <ncm@nospam.cantrip.org> wrote:
>
>>It is substantially harder, in general, to write a container that
>>doesn't use assignment.  It's trivial, though, to insert calls to
>>"unconst()" ...
>
>Your unconst function is far from trivial.  It is, for example,
>much harder to explain than the difference between assignment
>and initialization.

If there is anybody on this list who doesn't understand the
following template:

  template <class T>
    T* unconst(T const* p) { return const_cast<T*>(p); }

please speak up and prove Andrew's point.  When you do, tell us _also_
how easy you feel it is to implement all your containers without using
assignment.

If I understand Andrew's assertion correctly, we made a sweeping
change to the language solely to make marginally-useful containers
just slightly easier to implement using an odd style that avoids
assignment.

There must be some really compelling argument for the change that
just hasn't surfaced yet.  To me it's really interesting that such
weak arguments keep getting dragged out of their deathbeds and
forced to dance before being shot down again.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/27
Raw View
In article <37ED8810.66AC@wanadoo.fr>, Valentin Bonnard
<Bonnard.V@wanadoo.fr> writes
>Francis Glassborow wrote:
>
>> I would strongly favour the next version of the C++ standard (or even
>> via a corrigendum) providing another qualifier to inhibit destruction.
>
>void foo ()
>{
>    no_destroy int i;
>} // valid ?
>
>Not that i _is_ destroyed.

My intention was that we should provide a mechanism for qualifying
pointers at top level, nothing more (OK this will require thought when
we get to multiple levels of indirection)

I now wonder if top level const qualification on a pointer should do
what I want.  It is quite clear that delete applied to a pointer changes
the pointer (its value moves from determinate to undetermined).  The
pointer variable still exists but has changed.



Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/09/27
Raw View
ncm@nospam.cantrip.org (Nathan Myers) writes:

[...]

| The example above, for instance, appeared originally in the form:
|
|   template <class T> void f(T*) { T* p = new T; delete p; }
|
| with a note that it would fail if called on a pointer-to-const.
| I _immediately_ countered that if one wanted such a function to
| work with a pointer-to-const, it was sufficient to define a
| one-liner:
|
|   template <class U> void deleter(U const* p) { delete const_cast<U*>(p); }
|
| and write f() as
|
|   template <class T> void f(T*) { T* p = new T; deleter(p); }
|
| This was ignored, and the original example posted several more times
| with no comment on the criticism.  The example was later elaborated
| to involve a Container class, and the criticism was refined to provide
| a more general accommodation (unconst()) but no acknowledgement of
| (never mind defense from) the implications of the criticism has ever
| been posted.

As you noted in another posting, ARM's position on object destruction
through pointer-to-const was inconsistent.  At least the Standard is
consistent on that issue - notice that I'm not claiming the decision
made to change the ARM rule was right or a mistake, I leave it to more
knowledgeable people to make such a judgment.

Francis mentioned in an earlier posting that perhaps we should educate
C++ users not to use raw pointers and teach them how to use
"higher-level" pointers.  That alternative seems -to me- to be more
productive, in the sens that it would bring something very useful,
than moaning over a change (mistake?) made in the past.

You mentioned in another posting that with the ARM rule, a library
writer could release a pointer-to-const in the hands of an untrusted user
and expect him not to destroy the object pointed-to without some pain.

With Standard C++'s abstract expressionism, I would say nobody should
release a raw pointer (to const) in the nature. One should release a:

template<typename T>
class trustful_pointer_to_const {
public:
 trustful_pointer_to_const(const T* p = 0) : pointer(t) {}

 template<typename U>
 trustful_pointer_to_const(trustful_pointer_to_const<U> p)
  : pointer(p) {}

 const T& operator*() const { return *pointer; }

 const T* operator->() const { return poiner; }

 // Other useful member functions...

private:
 const T* pointer;

 // Not implemented
 operator T*() const; // or operator const T*() const
};


--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/27
Raw View
>Do the comments still reflect your thinking?

No.

>If not, why are the two situations different?


They might not be depending on your view. I view the association of
construction and destruction differently than I view the permission to
modify the object during its lifetime (after construction and up to but not
including destruction). This subject has been well-addressed in this thread,
and reasonable people disagree on it, to paraphrase one of the participants.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/27
Raw View
Edward Luke wrote in message ...
>Perhaps, but shouldn't the default be that const implies may not
>modify, and then an additional qualifier would be necessary to make it
>a deleteable const pointer?
>
>For example,
>
>const X *p ;  // Contents cannot be changed, pointer cannot be deleted
>destructable const X *p ; // This pointer can be deleted

But then how would you express that sth. is non-const yet
non-destructable?  This is something you would need a lot.  Making
unqualified types by default non-destructable would be a solution, but
then that would break heaps of old code.

- Anders
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/27
Raw View
ark@research.att.com (Andrew Koenig) wrote:
> Let's change the example very slightly:
>
>  template<class T> class X {
>
>   void f() {
>    T* p = new T;
>    delete p;
>   }
>  };
>
> Now, f did not choose to make a const pointer.  Nevertheless, inside
> an instantiation of X<const int>, f will be making a const pointer
> even though it did not choose to do so.

The person who instantiated X<const int> made the choice. So?

The aim of the ARM rule is to have the type system reject code like:

    void f( const int *px ) {
        delete px;
    }

Naturally we must also prevent:

    template <typename T>
    void f( T *px ) {
        delete px;
    }

being instantiated for <const int>, because it is the same thing. We can't
logically prevent that and yet allow:

    template <typename T>
    void g( T *px ) {
        px = new T;
        delete px;
    }

and there's no real reason why we should. The situation is very similar
to:

    class Test {
    public: void method();  // Not const!
    };

    template <typename T>
    void h( T *px ) {
        px = new T;
        px->method();
    }

Clearly h<const Test>() is not allowed (because method() is not const),
even though we created the T ourselves. Do you see? You might as well say,
"Now, h did not choose to make a const pointer.  Nevertheless, inside an
instantiation of h<const Test>, h will be making a const pointer even
though it did not choose to do so." So what? This is entirely reasonable
and expectable behaviour which, for h at least, no-one objects to.

As far as I can tell, people want to make a special exemption for delete
because of some general rule that "if you create it you can delete it".
But there is no such rule. Consider:

    class Test2 {
    public:
        Test2();
    protected:
        ~Test2();
    };

Clearly we cannot instantiate f<Test2>() whatever the rule for const
delete. Sometimes we can create objects we can't delete, and when that
happens we can't use those objects with templates which require delete.

Finally, as has been pointed out many times, templates with the behaviour
of g<const T> can be written if we take a little more care with their
implementation. We can always write them in a way which doesn't require us
to delete a const object. Nothing fundamental is lost.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/27
Raw View
blargg <postmast.root.admi.gov@iname.com> wrote:
> Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
>
>> Nathan ... has strongly questioned Andy Koenig's example (deleting
>> files).  Here is my best shot. ...
>> Andy's oft quoted example of Unix file destruction was intended to
>> highlight that 'read-only' does not subsume 'do not destroy' in at least
>> one place even though this is a surprise to naive users.
>
>Isn't this file system example an instance of indirection? The reference
>to the node is being deleted, not the actual node. The reference may say
>that it doesn't modify the file, but that doesn't mean the reference
>itself can't be destroyed. When no more references exist to the file, how
>can anyone tell if it exists? It's like garbage collection - no more
>references exists, so the program can't tell whether the object exists or
>not.

Yes.  The strictly valid analogy is:

  C++          Unix
  ---          ----
  T* p;        directory entry
  *T           file (inode)
  T const* p;  dir entry that refers to an unwritable file (rm allowed)
  T* const p;  entry in an unwritable dir  (rm forbidden)
  p = 0;       rm pathname
  GC           inode reference counts

Of course the analogy is functionally exact only in a garbage-collected
C/C++ runtime environment.  "rm"ing any entry in a writable directory
(regardless of whether the file (inode) is writable) is always permitted.
Assigning 0 to a pointer-to-const has always been permitted.

To allow deletion of pointer-to-const matches precisely with allowing
the actual file (inode) to be destroyed.  This is impossible in Unix.
It has been requested often, but not implemented for sound
engineering reasons.

The above is really quite elementary.  I'm most eager to learn why
someone familiar with all the parts would have trouble following it.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/27
Raw View
On 25 Sep 1999 16:20:51 GMT, Al Stevens <alstevens@midifitz.com> wrote:
>Nathan Myers wrote in message <37eb43b1$0$225@nntp1.ba.best.com>...

>> What, precisely, are we supposed to have got in exchange?

>Nathan, do _please_ pay attention.  Plenty of people have spoken up on
>both sides of the technical question. (Is there an echo in here?)  And that
>question has been answered. Not necessarily to everyone's satisfaction, but
>it was answered.

I must have missed the answer.  Can you please summarize?

--
--------------
siemel b naran
--------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1999/09/25
Raw View
Lisa Lippincott <lisa_lippincott@bigfix.com> writes:

>It is true that ARM C++ forbade the application of delete to a pointer
>to const.

It is also true that ARM C++ did _not_ forbid calling the destructor for
a const object.  Indeed it was explicitly allowed: "A destructor can be
invoked for a const or volatile object" [ARM 12.4, page 277].

--
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    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/25
Raw View

Nathan Myers wrote in message <37ea78e5$0$219@nntp1.ba.best.com>...

>Now that deletion of pointer-to-const without casting away const is
>legal, our need to deplore has increased.


You gain some, you lose some. On balance, where do you think we stand?




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/25
Raw View
Nathan Myers wrote in message <37eb43b1$0$225@nntp1.ba.best.com>...
> What, precisely, are we supposed to have got in exchange?


Nathan, do _please_ pay attention.  Plenty of people have spoken up on
both sides of the technical question. (Is there an echo in here?)  And that
question has been answered. Not necessarily to everyone's satisfaction, but
it was answered.



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: postmast.root.admi.gov@iname.com (blargg)
Date: 1999/09/25
Raw View
In article <vlbO1NAC1263EwzN@robinton.demon.co.uk>, Francis Glassborow
<francisG@robinton.demon.co.uk> wrote:

> Nathan has asked that we address the issue of why the C++ Standards
> Committees made a change to the behaviour of const.  At the same time he
> has strongly questioned Andy Koenig's example (deleting files).  Here is
> my best shot.
>
> The fundamental issue is our perception of what it means to be mutable.
[snip]
> Andy's oft quoted example of Unix file destruction was intended to
> highlight that 'read-only' does not subsume 'do not destroy' in at least
> one place even though this is a surprise to naive users.  I do not think
> (and I was there) that he was arguing from analogy, he was providing a
> counter example to those who would claim that destruction was
> necessarily a change to an object  (destruction is logically a change to
> the environment).  Once one can accept that in at least one place many
> people are happy with keeping destruction and change as orthogonal
> concepts it becomes possible to consider the benefits of considering
> this distinction elsewhere.

Isn't this file system example an instance of indirection? The reference
to the node is being deleted, not the actual node. The reference may say
that it doesn't modify the file, but that doesn't mean the reference
itself can't be destroyed. When no more references exist to the file, how
can anyone tell if it exists? It's like garbage collection - no more
references exists, so the program can't tell whether the object exists or
not.

[snip]


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Nathan Myers <ncm@best.com>
Date: 1999/09/25
Raw View
References: <sa5aerd1ltp.fsf@dune.gia.rwth-aachen.de> <6hxG3.12178$F07.356585@newscene.newscene.com> <37EBAB80.2DF2@smarts.com> <FIKuIx.DLu@research.att.com>

Andrew Koenig <ark@research.att.com> wrote:
>Let's change the example very slightly:
>
> template<class T> class X {
>  void f() { T* p = new T; delete p; }
> };
>
>Now, f did not choose to make a const pointer.  Nevertheless, inside
>an instantiation of X<const int>, f will be making a const pointer
>even though it did not choose to do so.

Let's change the example very slightly:

 template<class T> class X {
  void g() { T* p = new T; *p = T(); }
 };

"Now, g did not choose to make a const pointer.  Nevertheless, inside
an instantiation of X<const int>, g will be making a const pointer
even though it did not choose to do so."

Any such argument you can make in favor of allowing deletion of a
pointer-to-const applies identically to assignment.  Again, the
language doesn't actually prevent you from accomplishing what is
attempted above:

 template <class U> U* unconst(U const* p) {
         return const_cast<U*>(p);
 }
 template<class T> class X {
  void f() { T* p = new T; delete unconst(p); }
 };
 template<class T> class X {
  void g() { T* p = new T; *unconst(p) = T(); }
 };

but it does (or used to!) prevent you from doing it accidentally.

Andrew's example above has been posted many times before, and
responses demonstrating its invalidity as well.  The criticism
has never been acknowledged.  Why not?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/25
Raw View
Francis Glassborow wrote in message ...
>In article <slrn7uaduu.pla.sbnaran@localhost.localdomain>, Siemel B.
>Naran <sbnaran@uiuc.edu> writes
>>But what about the more general case where we must pass a pointer to
>>non-const House?  Now what's there to prevent clients from delete the
>>pointer?  Nothing.  That's why I'm not convinced that this argument
>>about whether or not we should be able to delete a pointer to const
>>is a useful argument.
>
>Yes, I think I am coming round to the view that we should consider some
>way of providing a 'may not delete through this pointer/reference'
>property quite distinct from 'may not modify...'


Please, no.  Think about how trouble we have today managing const and
non-const versions of stuff.  Do you really want to write 4 versions of
the same member function, one for each combination of modifiers?

And why stop at that... we need also to distinguish between a strong and
a weak version of const, as const today means something different in
different contexts. (See also Andrew Koenigs 24 Sep 1999 07:33:20 GMT
posting on this subject.)
    int const ROMable_int = 42;
The strong version, because
    const_cast<int&>(ROMable_int) = 5;
violates the contract with the implementation, yielding undefined
behaviour.
The weak version:
    void f(int const& i);
is just a contract between different parts of the program, and may be
broken using const_cast without causing undefined behaviour.  Now,
allowing
    f(ROMable_int);
is really a sort of a hole in the type system, since f has a weaker
contract than is required by ROMable_int.

IMO introducing more type modifiers has the potential to be a major
pain, and promises very little benefit.

- Anders




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/25
Raw View
francis@robinton.demon.co.uk (Francis Glassborow) wrote:
> Andy's oft quoted example of Unix file destruction was intended to
> highlight that 'read-only' does not subsume 'do not destroy' in at least
> one place even though this is a surprise to naive users.  I do not think
> (and I was there) that he was arguing from analogy, he was providing a
> counter example to those who would claim that destruction was
> necessarily a change to an object  (destruction is logically a change to
> the environment).

I think this is wrong, because in Unix "unlink" does not equate to
"delete". If you unlink a file, the file still exists, as you can verify
by looking at it through another link. Even if there are no more links, if
the file is still held open by some process that process can read the file
and verify it still exists.

The file is *never* deleted. It simply becomes inaccessible. What the
operating system does with inaccessible files is speculation. We can't
tell. If we could tell, the file wouldn't be inaccessible.

Destruction itself is not a change to the environment in Unix. The change
has already happened - the directory link has been removed, the file
handle closed. These things can happen without destruction ensuing. The
nearest thing to an environment change is that a bit more memory may
magically become available to the file system, but you can't point to that
memory and say, "That's my file!" because it isn't.

On the question of whether deletion is a change to an object, Unix is
silent.


> On the one side Nathan maintains that ending an objects existence is a
> change to the object.  On the other side we have those that (even if
> unconsciously) believe that you cannot logically talk about change to
> something that does not exist any longer.

The C++ situation is different precisely because there may have been other
references to the deleted object. It's these references we care about.
Whether or not the object itself changes, "*p" certainly does. It becomes
undefined behaviour. There is no analogy to this in the Unix file system.

It's this change to "*p" that's the problem, both theoretically and
practically. Philosophical discourse about possibly non-existent objects
is beside the point.


> I would strongly favour the next version of the C++ standard (or even
> via a corrigendum) providing another qualifier to inhibit destruction.

I'm not sure I agree that the extra language complexity is worth it. The
ARM rule already covered the most important cases without any extra
syntax. The other cases can already be expressed by other language
constructs - for example by factoring interfaces using inheritance, or by
using wrapper classes, or by writing more specific templates. Admittedly
they are clumsy, but the rare cases are doable. The main thing is to get
the defaults right for the common cases.

In my view "const" should mean non-deletable by default. This is for two
reasons. Firstly, it's safer. Just as "class" means that members default
to private unless explicitly made more public, so "const" should mean no
change allowed unless specific directives say otherwise. (Non-const could
reasonably go to the other extreme - deletion allowed unless otherwise
prohibited - by analogy with "struct". Exactly the ARM rule.) Secondly,
it's what real code will want 99% of the time. We're really struggling to
come up with cases where deleting a const object makes sense at all.

If your proposed new qualifier achieves that default, fine. That will be
tantamount to admitting the ARM rule was right. We could have kept the ARM
rule and still added your qualifier later.

More likely, because the rule has been changed and changing it back again
now could break code, you will have "const" default to the wrong thing. It
will be like "explicit" all over again. Almost every function parameter
everywhere will need to have this new qualifier added. Code will get
correspondingly messier and more verbose. Quite likely people will be lazy
and not bother, and for them it will be as if your new qualifier had never
been added. It's not worth it.

This is in addition to all the usual problems of language change. Do we
introduce a new keyword and break programs that use it as a variable name?
Or do we overload an existing keyword yet again? Or do we introduce some
weird syntax, like "=0" for abstract virtual functions? There is no good
choice.


> Finally, note that Nathan's puzzlement (about the Committees' decision)
> is, IMO, rooted in his belief that the decision is fundamentally flawed.
> Most of us in the room at the time had, at least implicitly, an
> understanding of the fundamental issue and were helped by Andy's
> example.  I, and I suspect most others, did not consider this argument
> by analogy.

I agree with you that it's premature to discuss why people made a mistake
before there is a consensus that they did, in fact, make a mistake. On the
other hand, I agree with him that a mistake was made. In truth, the
committee *did not* introduce a new "deletable" qualifier. As I argue
above, they changed the language in a way which makes it harder to get the
new qualifier added with the right defaults.

It all very well to say they understood the fundamental issues, but in my
view they went ahead and did the wrong thing.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/25
Raw View
On 24 Sep 1999 16:24:58 GMT, Francis Glassborow

>Now the question that follows (if you are willing to accept that there
>is more than one way to consider the concept of read-only as embodied in
>C++ usage of const) is what benefits accrue to either view.  Nathan's
>view does not seem to buy us anything useful.  Indeed as long as you

In all fairness, Koenig's view doesn't buy us anything useful either.


>maintain that view it is difficult, if not impossible, to see and tackle
>the underlying problem that regardless as to an objects mutability we
>may separately wish to specify it destructibility.

--
--------------
siemel b naran
--------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/25
Raw View
In article <37ea78e5$0$219@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>Before we had type checking, we deplored storing a float into an int
>variable; now it's a compile error message, and our need to deplore it
>has been swallowed up into deploring insertion of casts to persuade
>the compiler to do unsafe things.

Are you using the same languages that I am?



Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: niklasb@my-deja.com
Date: 1999/09/25
Raw View
In article <slrn7uj3sd.qqr.sbnaran@localhost.localdomain>,
  sbnaran@uiuc.edu wrote:
>
> On 23 Sep 1999 00:27:53 GMT, niklasb@my-deja.com <niklasb@my-
deja.com> wrote:
>
> >> On the other hand, it is rare to pass a pointer to non-const
> >> House to outside clients, at least in my experience.
>
> 'outside' clients: basically anyone
> 'inside'  clients: basically helper functions
>
> >> The reason is that when outside clients modify the House the
> >> class that owns the Houses, namely class List_of_Houses, must
> >> know of the change so that it can maintain its invariants.
>
> >Out parameters and in/out parameters are pretty common:
> >
> >  void Func()
> >  {
> >    MyInfo info;
> >    GetSomeInfo(&info); // non-const pointer
> >    DoStuff(info);      // const reference
> >  }
>
> You pass a non-const pointer to an outside client?
>
> Very brave indeed.
> Actually, I do this myself sometimes.  I follow the coding style
> that variables passed by pointer to non-const may be modified.

Yes, the definition of an out parameter is that it may be
(and usually is) modified. Generally, the only reason to
pass a non-const pointer to a function is if you expect it
to modify the object pointed to.

> However, most times I use return by value.  It is better to see
>    /*const*/ MyInfo info=GetSomeInfo();
>
> It is rare to pass by pointer to non-const, at least for me.

Return by value is often cleaner and more natural, but the
use of out and in/out parameters is still common practice.
Perhaps not for you, but for many others.

For example, comp.lang.c++.moderated recently had a lengthy
thread about whether out parameters should be declared as
pointers or references. There seemed to be considerable
interest in this question, and I don't recall anyone arguing
that out parameters should simply be avoided.

Also, out parameters can do things return by value cannot.
Just off the top of my head, you might pass a pointer to
object with (non-const) virtual functions, with the
expectation that the outside code would call those
functions.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: niklasb@my-deja.com
Date: 1999/09/25
Raw View
In article <FIIM9r.EB9@research.att.com>,
  ark@research.att.com (Andrew Koenig) wrote:
>
>...
>
> Similarly, before you destroy an object whose address you are
> given, you must know through other sources that it is safe to
> do so.  In particular, it is not nearly enough that the object
> be modifiable -- it must have been an object that was obtained
> by calling new.

Moreover, you must (obviously) also know that no other code
is going to use or delete the object.

> Therefore, a program that might delete an object that it is given
> had better say so in its description, every bit as much as a
> function that might cast away a const that it was given.

Yes! If a programmers are inclined to delete pointers at
random, without actually knowing whether it is appropriate,
then woe to them! Preventing deletion of pointers to const
would catch at most a fraction of such errors. That's pretty
feeble protection.

This is relevant to the trade-off between the alleged greater
safety of the ARM rules and the greater convenience and utility
of the current rules. It makes sense to ask how much safety
we gave up, and the answer is very little.

In exchange, the current rules allow some valid and useful
code to be implemented without casting:

  template<class T>
  void g(...) {
 T* p = new T;
 ...
 delete p; // T may be const
  }

  Container<const T> // good
  SmartPtr<const T> // good

I have no comment on how the standards debate was conducted
because I didn't participate, but I am happy with the end
result. IMO, the current rules make sense and make
appropriate trade-offs.


Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/24
Raw View
Al Stevens <alstevens@midifitz.com> wrote:
>Nathan Myers wrote:
>>We must begin by locating someone who thought the breakage was a good
>>idea, but is able to comprehend what is wrong with the arguments that
>>were presented in its favor.
>
>If virtually no one in a such a talented group supported a position
>of mine, then I would have to rethink my position.

Al, do _please_ pay attention.  Plenty of people have spoken up on
both sides of the technical question.  Presumably somebody who likes
the status quo but understands what's wrong with the previously
presented arguments for it will have some _other_ reasons for liking
it, but we don't need to know them.

>You have focused this conversation on the arguments being given
>and your perception of the mental acuity of their proponents rather
>than the technical merits of the issue itself, where I think it belongs.

I have focused this conversation on the arguments being given.
The technical merits of the issue itself are, as has already been
noted repeatedly, moot, except as they illustrate events.

>Rather than
>counter those arguments, you simply tell us that they are wrong.

Each argument has been countered at length, and repeatedly.  They have
not all been "wrong", per se, but they all fail to support the position
they supposedly argue for.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/24
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>Dave Harris <scorp@btinternet.com> writes
>>Also there are things we can do for the future. One is to publicly deplore
>>the practice of deleting const pointers.
>
>I think we need something much stronger, we need to publicly deplore
>destroying objects through pointers passed as arguments.

Before we had type checking, we deplored storing a float into an int
variable; now it's a compile error message, and our need to deplore it
has been swallowed up into deploring insertion of casts to persuade
the compiler to do unsafe things.  Progress is measured in how few
things we need to deplore.

Now that deletion of pointer-to-const without casting away const is
legal, our need to deplore has increased.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/24
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
>
>>I think we need something much stronger, we need to publicly deplore
>>destroying objects through pointers passed as arguments.
>
>Actually, I once wrote an article about a closely related topic,
>namely the possibility that a function might modify a const
>argument whose address it is passed.
>
>Consider the following:
>
> void clobber(const int* xp) { *const_cast<int*>(xp) = 0; }
> int main()                  { int x; clobber(&x); }

>My question was:  Is this example well formed, and does it behave
>in a well defined way at run time?
>
>The answer is yes to both questions!  There's nothing wrong with
>casting away a const that didn't need to be there in the first
>place -- in this case, the one that resulted from converting
>&x from int* to const int*.

Right.  Just as there was never any problem with deleting the referent
of a pointer-to-const got by operator new.

>So then the question is: How can we trust that *any* function
>that takes a pointer to const as its argument won't clobber the
>argument?

Because in order to clobber it, the function must use a cast.
You cannot use a cast accidentally, and any problem caused by
using a cast improperly is well beyond help from the language.

>My conclusion was that the function itself doesn't have any way
>of knowing that it wasn't called this way:
>
> const int x = 42;
> clobber(&x);
>
>in which case the effect of clobber is undefined.  In other words,
>before you cast away a const, you have to know through other
>sources that it is safe to do so.

Exactly.  Demanding that certification was a service the language
performed, and still does for operator=, but no longer does for
operator delete.

>Similarly, before you destroy an object whose address you are
>given, you must know through other sources that it is safe to
>do so.  In particular, it is not nearly enough that the object
>be modifiable -- it must have been an object that was obtained
>by calling new.

The interesting case was in the other direction: it was entirely
enough to know that the object was not modifiable -- you didn't
even need to know whether it was obtained by calling new, you
couldn't delete it without writing out a cast.

>Therefore, a program that might delete an object that it is given
>had better say so in its description, every bit as much as a
>function that might cast away a const that it was given.

It "had better", but the language no longer provides the assistance
it once did.  What, precisely, are we supposed to have got in exchange?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/24
Raw View
Nathan has asked that we address the issue of why the C++ Standards
Committees made a change to the behaviour of const.  At the same time he
has strongly questioned Andy Koenig's example (deleting files).  Here is
my best shot.

The fundamental issue is our perception of what it means to be mutable.
Nathan takes the view that immutability includes the concept of non-
destruction.  This is a perfectly reasonable view but not the only one.
Logically what can you say about something that no longer exists?
(actually that is stronger than the material concept of destruction,
which may lie at the root of the alternative views)

I can remember endless academic arguments about whether existence is a
predicate and the claim that ceasing to exist is a change to an object
has a strong flavour of these arguments.

On the one side Nathan maintains that ending an objects existence is a
change to the object.  On the other side we have those that (even if
unconsciously) believe that you cannot logically talk about change to
something that does not exist any longer.

Andy's oft quoted example of Unix file destruction was intended to
highlight that 'read-only' does not subsume 'do not destroy' in at least
one place even though this is a surprise to naive users.  I do not think
(and I was there) that he was arguing from analogy, he was providing a
counter example to those who would claim that destruction was
necessarily a change to an object  (destruction is logically a change to
the environment).  Once one can accept that in at least one place many
people are happy with keeping destruction and change as orthogonal
concepts it becomes possible to consider the benefits of considering
this distinction elsewhere.

I have to say that much of what Nathan has posted to this thread
suggests that he has somehow fixated on a specific view of what it means
to be const (immutable).

Now the question that follows (if you are willing to accept that there
is more than one way to consider the concept of read-only as embodied in
C++ usage of const) is what benefits accrue to either view.  Nathan's
view does not seem to buy us anything useful.  Indeed as long as you
maintain that view it is difficult, if not impossible, to see and tackle
the underlying problem that regardless as to an objects mutability we
may separately wish to specify it destructibility.

Though it may not have been viewed with this degree of clarity at the
time (understanding often takes time) I think that the Committees'
decision was correct because it now enables us to tackle the problem of
destructibility as a separate issue.

I would strongly favour the next version of the C++ standard (or even
via a corrigendum) providing another qualifier to inhibit destruction.
Then I could teach programmers to use it in very much the way that I
used to teach C programmers to qualify file scope identifiers as
'static' until they new that they wanted to make them globally
meaningful.

Finally, note that Nathan's puzzlement (about the Committees' decision)
is, IMO, rooted in his belief that the decision is fundamentally flawed.
Most of us in the room at the time had, at least implicitly, an
understanding of the fundamental issue and were helped by Andy's
example.  I, and I suspect most others, did not consider this argument
by analogy.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jerry Leichter <jerrold.leichter@smarts.com>
Date: 1999/09/24
Raw View
| ////////////////// 1 /////////////////
| void f(const char* p)
| {
|   // ...
|   delete p;    // f deletes p. bad (IMO)
| }
| ////////////////// 2 /////////////////
| void f()
| {
|   const D* dp = new D(1,2,3);
|   // ...
|   delete dp;    // f created it, f destroys it. good (IMO).
| }

Let's change this very slightly:

| ////////////////// 1 /////////////////
| void f(const char* p)
| {
|   // ...
|   *p = 'x';    // f changes *p. bad (IMO)
| }
| ////////////////// 2 /////////////////
| void f()
| {
|   const D* dp = new D(1,2,3);
|   // ...
|   *dp.firstField = 10;
|    // f created it, f initialized it, f changes it.
|    // good (IMO).
| }

Do the comments still reflect your thinking?  If not, why are the two
situations different?

f() chose to make a const pointer.  That's imposing a constraint on
itself.  The constraint is quite weak:  It only says that the object
will not be changed *through that pointer*.  f() can always use casting,
but in this case, it doesn't even have to:  Since it's creating the
object, it can easily save away a non-const pointer, to be used when f()
wants to modify the object.  Put another way:  f() *had* a non-const
pointer to the created object - new returned it.  It chose to throw it
away.  Maybe it had a reason!  Code that saves away the non-const
pointer is just as simple, more clearly indicates what f() is doing, and
involves nothing undefined at all (as casting away constness might).

Why insist on a way to write something obscurely when there is already a
way to write it clearly?
       -- Jerry


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/09/24
Raw View
In article <37EBAB80.2DF2@smarts.com>,
Jerry Leichter  <jerrold.leichter@smarts.com> wrote:

>| ////////////////// 1 /////////////////
>| void f(const char* p)
>| {
>|   // ...
>|   *p = 'x';    // f changes *p. bad (IMO)
>| }
>| ////////////////// 2 /////////////////
>| void f()
>| {
>|   const D* dp = new D(1,2,3);
>|   // ...
>|   *dp.firstField = 10;
>|    // f created it, f initialized it, f changes it.
>|    // good (IMO).
>| }
>

>f() chose to make a const pointer.  That's imposing a constraint on
>itself.  The constraint is quite weak:  It only says that the object
>will not be changed *through that pointer*.  f() can always use casting,
>but in this case, it doesn't even have to:  Since it's creating the
>object, it can easily save away a non-const pointer, to be used when f()
>wants to modify the object.

Let's change the example very slightly:

 template<class T> class X {

  void f() {
   T* p = new T;
   delete p;
  }
 };

Now, f did not choose to make a const pointer.  Nevertheless, inside
an instantiation of X<const int>, f will be making a const pointer
even though it did not choose to do so.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jeff Rife <wevsr@nabs.net>
Date: 1999/09/24
Raw View
Nathan Myers (ncm@nospam.cantrip.org) wrote:

> In fact, the language _always_ allowed programs to delete all objects
> they allocated.  If Andrew knows of any case where it may not have
> allowed it, he should identify it.  (Every example he has advanced
> thus far has been eliminated, although he has never acknowledged it.)
>
> If by "fudging", Andrew refers to the legality of casting away const
> on a pointer returned by "new const T", I remind the reader that the
> equivalence between "new const T" and "new T" was broken *after*
> const itself was broken.  (This has been noted before in this forum.)

So, according to the ARM, the following statements are equivalent...

T const * ta = new T();
T const * tb = new const T();

...and both are intepreted as:

T const * t = new T();

Thus, casting away the const and deleting is OK, because the underlying
object is *not* const.

In the ISO/ANSI standard, the two lines are interpreted exactly as written,
and are, thus, different.

OK, now, let's bring a function into play, because formal parameters to
functions are the crux of this argument.

void foo(T const *pT)
{
delete pT;
}

(Let us assume that pT points to an object that was allocated with new,
because, if not, all bets are off, because that invokes undefined
behavior, no matter what.)

For an ARM-compliant implementation, this function fails to compile,
but for an ISO/ANSI standard implementation, this code works, and deletes
our object (although it might invoke undefined behavior if the underlying
object actually *is* const), which is what people are complaining about.

But, let's try:

void bar(T const *pT)
{
delete const_cast<T *>(pT);
}

Hey, guess what, this compiles under the ARM and doesn't invoke undefined
behavior, because the underlying object *cannot* be const, if it was
allocated on the heap.

It also compiles under ISO/ANSI, but *might* invoke undefined behavior, as
the underlying object might actually *be* const...which is exactly the
same as the function foo above.

Thus, it turns out that by allowing deletion through a const pointer,
and actually allowing the creation of a const object through new, the
ISO/ANSI standard is somewhat safer, because the const_cast could *always*
do the delete for ARM code.

--
Jeff Rife                   | "Wow, I've never seen you this
19445 Saint Johnsbury Lane  |  bitter...I like it."
Germantown, MD  20876-1610  |              -- Richard Karinsky, "Caroline in the City"
Home: 301-916-8131          |
Work: 301-770-5800 Ext 5335 |
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 1999/09/23
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> wrote:
> I think we need something much stronger, we need to publicly deplore
> destroying objects through pointers passed as arguments.  Actually,
> deplore is too strong, we need to teach programmers that this is
> dangerous and must only be done with a fully documented justification.

I don't think deplore is too strong.  In my experience, any use of new
or delete outside of the implementation of a resource-managing smart
pointer is suspect.  (As Herb Sutter has pointed out, even an innocent
expression like std::auto_ptr<T>( new T ) can be problematic.)

"If I have a pointer, it must be OK to delete it" may be the worst
common misconception among new programmers today.

> Note that the danger is compounded by the problem of pointers not
> carrying information with them as to whether they point to deletable
> data and whether the pointer points to an object or an array.

Or, for that matter, which parameters were used for a placement
allocation function.

                                                   --Lisa Lippincott


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/23
Raw View

Nathan Myers wrote in message <37e975d2$0$201@nntp1.ba.best.com>...
>>You will agree that this is not the only case where that happened. ...
>
>Irrelevant.  Breaking a feature may be necessary, but one expects
>to see good reasons for it.

The end justifies the means? Depends on where you stand on the end and the
means. That's why laws can be codified and justice cannot. The merits of the
change might very well be overridden by the volume of code that stands to be
broken, past or future. But how do you know that? The best a committee can
do is make judgements based on their own experience and react to public
review of the proposal. I see two concerns about the process and its
timeliness: did the public have enough time to evaluate the change and, if
so, were they well-informed enough by the committee about the implications
of the change to provide educated feedback. If the answer to either question
is no, then the change should not have been voted on much less voted in. But
if established procedure was followed properly for submission, deliberation,
and voting, you have no complaint coming. Those are the rules. You agree to
them when you join up. I get to complain because I didn't join, but you
don't because you did.

>>>... very little discussion or analysis was permitted.
>>... I conclude from this discussion that there was much debate about this
particular issue ...

>Please reread the sentence you are responding to.

I read it. So what? You say "very little." I say "much." Two vague and
unspecific measures. Perhaps they both mean the same amount of discussion.
You like a lot of debate? I don't. I like to hear the issues presented, the
arguments presented by all sides (once, please), and then I can go off,
cogitate about it, come back and vote. But then, I wasn't there and you
were.


>We must begin by locating someone who thought the breakage was a good idea,
>but is able to comprehend what is wrong with the arguments that were
presented
>in its favor.  That had _seemed_ easy.


Maybe that should tell you something. If virtually no one in a such a
talented group supported a position of mine, then I would have to rethink my
position. You have focused this conversation on the arguments being given
and your perception of the mental acuity of their proponents rather than the
technical merits of the issue itself, where I think it belongs. Rather than
counter those arguments, you simply tell us that they are wrong. Not many
people are buying into that position. I'd rethink it if that happened to me.

Here's my take on the issue without getting into all the template stuff.
Forgive me if I cover a lot of old territory; I'd like to get it all down in
one place and I'd like it to be as simple as possible. Consider again these
two idioms, which seem to be at the foundation of the issue:

////////////////// 1 /////////////////
void f(const char* p)
{
  // ...
  delete p;    // f deletes p. bad (IMO)
}
////////////////// 2 /////////////////
void f()
{
  const D* dp = new D(1,2,3);
  // ...
  delete dp;    // f created it, f destroys it. good (IMO).
}

(None of MOs are H.)

If the only way to prevent the first is to disallow the second, then that's
how it should be, and that got broken, in my opinion. All the arguments
against permitting the first idiom are valid, says I. It should not be
permitted at any cost, not even to gain the convenience of the second idiom.

But I want the second idiom. (Well, I don't really care all that much to
have it, but many do.)

If the only way to allow the second is to allow the first, then the language
needs something more, because as I already opined, the first is
unacceptable. The arguments I've heard against the second idiom are not as
convincing, in my opinion. The arguments in its favor do have merit in my
view. Yet the second idiom has always been available under the old way by
the application of a cast. Okay, you don't like casts. Neither do I, and I
use them all the time. I wish we could have it both ways.

Does the change in behavior (what some would call the "broken feature")
break any existing code? I don't think so. All the existing code that used
to work didn't delete const pointers because it couldn't, so nothing about
the change hurts any of that old code, at least not when you consider only
the two idioms I used here as examples. (I am not concerned about the
effects on templates if for no other reason than that feature is still in
its infancy, too.) Does the change break future code? Depends on how careful
you are.

It sure mandates some programming style guide subjects that we didn't have
before. I hate programming style guides.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/23
Raw View
In article <memo.19990921215210.64745A@btinternet.com>, Dave Harris
<scorp@btinternet.com> writes
>Also there are things we can do for the future. One is to publicly deplore
>the practice of deleting const pointers. Another is to encourage compiler
>vendors to issue warnings when it happens. If we agree to start doing
>these things now, perhaps in 5 years we can get the standard changed.
>Bigger changes have been made in the past.

I think we need something much stronger, we need to publicly deplore
destroying objects through pointers passed as arguments.  Actually,
deplore is too strong, we need to teach programmers that this is
dangerous and must only be done with a fully documented justification.
Note that the danger is compounded by the problem of pointers not
carrying information with them as to whether they point to deletable
data and whether the pointer points to an object or an array (ironically
delete this is probably less vulnerable to this problem than other
pointers)


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Gabriel Dos_Reis <gdosreis@korrigan.inria.fr>
Date: 1999/09/23
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:

[...]

| We have two options:
|
| progressively remove the use of raw pointers from code (and change the
| way we teach newcomers)

This is indeed a rewarding option.

--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/23
Raw View
Bjarne Stroustrup wrote in message ...
>However, we have a standard, the standard
>is clear on this issue, and I think our energies are better spent on
other
>issues.

Tell that to the participants in the "Why's of C++ -- Part 3 (string
discussion)" thread <g>.  Amazing how much traffic is generated debating
an issue with virtually no practical significance.

_This_ debate is about understanding what constness is, which is
something I consider important.

- Anders
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/23
Raw View
Al Stevens <alstevens@midifitz.com> wrote:
>Nathan Myers wrote in message <37e7ed42$0$201@nntp1.ba.best.com>...
>
>>"Broken", in standardization,
>>has a strictly technical meaning: the definition was changed
>>in a way that makes existing code no long work the same way.
>
>You will agree that this is not the only case where that happened. ...

Irrelevant.  Breaking a feature may be necessary, but one expects
to see good reasons for it.

>>There is no question but that [breakage] occurred, and quite late
>>in the standardization process, and very little discussion or
>>analysis was permitted.
>
>... I conclude from this discussion that there was much debate about
>this particular issue ...

Please reread the sentence you are responding to.

>This issue ... expose[s] what looks like an anomaly in the language--not
>something that used to work and was broken or used to be broken and got
>fixed--but something that used to work for some purposes and not for others
>and now has the opposite behavior.

Yes.  As _has_ been mentioned already, the merits of the two alternatives
cannot be judged without reference to their effects on real programming.
Yet, the arguments advanced in favor of the change at the time made no
such reference, and the apologetics presented lately continue to fail in
the same way.

The issue (trying to be) under discussion is how such arguments can seem
persuasive to intelligent people.  We seem to continue to be sidetracked
with the need to demonstrate, repeatedly, the unsoundness of the arguments,
and (amazingly!) the unsoundness of _new_ arguments.  Eventually I hope to
bring discussion around to the original point.

We must begin by locating someone who thought the breakage was a good idea,
but is able to comprehend what is wrong with the arguments that were presented
in its favor.  That had _seemed_ easy.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/23
Raw View
On 23 Sep 1999 00:27:53 GMT, niklasb@my-deja.com <niklasb@my-deja.com> wrote:

>> On the other hand, it is rare to pass a pointer to non-const
>> House to outside clients, at least in my experience.

'outside' clients: basically anyone
'inside'  clients: basically helper functions

>> The reason is that when outside clients modify the House the
>> class that owns the Houses, namely class List_of_Houses, must
>> know of the change so that it can maintain its invariants.

>Out parameters and in/out parameters are pretty common:
>
>  void Func()
>  {
>    MyInfo info;
>    GetSomeInfo(&info); // non-const pointer
>    DoStuff(info);      // const reference
>  }

You pass a non-const pointer to an outside client?

Very brave indeed.
Actually, I do this myself sometimes.  I follow the coding style
that variables passed by pointer to non-const may be modified.

However, most times I use return by value.  It is better to see
   /*const*/ MyInfo info=GetSomeInfo();

It is rare to pass by pointer to non-const, at least for me.

--
--------------
siemel b naran
--------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Al Stevens" <alstevens@midifitz.com>
Date: 1999/09/22
Raw View
Nathan Myers wrote in message <37e7ed42$0$201@nntp1.ba.best.com>...

>You cannot decide which is better without analyzing the
>consequences of the alternatives.  "Broken", in standardization,
>has a strictly technical meaning: the definition was changed
>in a way that makes existing code no long work the same way.


You will agree that this is not the only case where that happened. There is
precedent. The changing of the scope rules in for-expression declarations is
one that comes to mind. The need to cast non-char* pointers in calls to
istream::read and ostream::write is another. The introduction of new
keywords (namespace, mutable, explicit, etc.) that can collide with
identifiers in existing code is an obvious third. Some of these changes
generate no diagnostic in existing code making them difficult to find;
others are found right away when you compile with a new compiler. It has
been my limited observation that the issue of broken code is treated as
important only when it supports arguments against a change in one of these
debates. When a favored change breaks code, broken code seems not as
important to the proponents. That's human nature.

All of which is to be expected when a standardization effort takes upon
itself the task of language invention rather than only formal language
definition and specification.

>There is no question but that that occurred, and quite late in the
>standardization process, and very little discussion or analysis
>was permitted.

Those of us who did not participate must assume that the committee weighed
all such changes and their potential effect on existing code before voting
them in. I conclude from this discussion that there was much debate about
this particular issue and that it probably heated up from time to time. The
fact of when it occurred--early, late--during the process is irrelevant. The
amount of discussion is, too, in hindsight. It seems clear to me that the
opposite yet rational (despite assertions to the contrary) arguments that
continue here means that no amount of additional debate would have changed
the minds of the opponents or altered the outcome. To do that would have
required politicking, which might be what you did not have enough time to
do. But technical issues should be resolved based on their technical merit,
not by political measures--influence brokering, favor exchanging, reciprocal
back-scratching and so on. Not that any of that ever happened with this
particular committee.

This issue, the arguments it raises, and the credentials and eloquence of
both camps really expose what looks like an anomoly in the language--not
something that used to work and was broken or used to be broken and got
fixed--but something that used to work for some purposes and not for others
and now has the opposite behavior. Which of the evils is lesser is not as
clear to me as it is to some of you.

And if you consider that to be the specious, irrational argument of an
otherwise reasonable, intelligent observer, then I thank you for
acknowledging my reason and intelligence and forgive you the rest.




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: niklasb@my-deja.com
Date: 1999/09/23
Raw View
In article <FIDzsx.GE0@research.att.com>,
  bs@research.att.com (Bjarne Stroustrup) wrote:
> niklasb@my-deja.com writes:
>
>  > I wonder, did const really have one particular meaning before
>  > C++ was standardized? I looked in the C++ Programming Language
>  > second edition (Stroustrup 1991), and I could find no mention
>  > of whether deleting a pointer to const is illegal. It seems
>  > likely that compilers differed in this respect. If so, any
>  > decision the committee made would represent a change to some.
>
> In the ARM, I'm quite explicit (ARM "5.3.4 Delete" pg 63):
>
>  A pointer to constant cannot be deleted.

I stand corrected on this historical point. I wondered whether
this might be a gray area that the standard clarified; but evidently
it was an explicit rule that the standard changed.

>
>  [ The resason is that the deletion in principle modifies the
object
>    pointed to. For example:

I'm not sure I agree that this is necessarily true in principle.
I don't believe it is inconsistent to say, "Deletion ends the
lifetime of the object pointed to; this does not constitute
modifying the object."

Nevertheless, it seems I missed the thrust of the discussion.
I was concerned merely with whether the current rules made sense.
Others were concerned with the decision process that led to the
current rules.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/23
Raw View
Francis Glassborow  <francisG@robinton.demon.co.uk> wrote:
> Nathan Myers ><ncm@nospam.cantrip.org> writes
>>... it doesn't matter whether breaking const was right or wrong:
>>the standard is what it is.  It does matter that "what it is" resulted
>>from nonsensical arguments, because we should be equipped to recognize
>>when a design issue arises which derails intelligent individuals'
>>reasoning skills this way.
>
>Nathan, much as I respect ... your frustration
>that otherwise intelligent people seem unable to agree with you ...

I have not asked anybody to agree with me.  (Some intelligent people
have done so anyhow.)  The goal, as quoted _immediately_ above, is
to explore what made certain specious arguments seem persuasive to
otherwise intelligent people.

If I am frustrated, it is that so many postings here entirely miss
the point.  If someone were to disagree in a way that betrays
an understooding of the issue, I would be ecstatic.

>... Normally functions should not destroy objects that have been lent
>to them. ... note the rules are entirely different for return values
>where licence to delete should be the norm.

What a remarkable statement.

>this discussion ... has clarified in my mind
>what the real issues are.  That is what we should focus on rather than
>sterile arguments about whether the Standards Committees should or
>should not have made a change.

Evidently it has not clarified much.  Quoting from the original posting:
>>... it doesn't matter whether breaking const was right or wrong:
>>the standard is what it is.
The discussion is not about sterile "shoulds", as much as it has been
sidetracked.  The discussion is about what went wrong, so that similar
mistakes can be avoided.

By the evidence, it appears we are doomed.

But I will try one more time: what was it about the issue, or the
(demonstrably specious) arguments that prevailed, that prevented
intelligent people then (and, apparently, still!) from applying their
critical faculties to the matter, and recognizing the glaring flaws
in the arguments used?

How can we recognize similar issues in the future?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: niklasb@my-deja.com
Date: 1999/09/23
Raw View
In article <37e7ed42$0$201@nntp1.ba.best.com>,
  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>
> <niklasb@my-deja.com> wrote:
> >  ncm@nospam.cantrip.org (Nathan Myers) wrote:
> >> <niklasb@my-deja.com> wrote:
> >> >Whether 'delete pointer-to-const' should be legal is a
> >> >practical question, the answer to which does not follow
> >> >inevitably from the internal logic of the language.
> >>
> >> Correct.  Engineering consequences matter.
> >
> >And neither definition of const is inherently more logical
> >than the other. Nor is either inherently "broken".
>
> You cannot decide which is better without analyzing the
> consequences of the alternatives.  "Broken", in standardization,
> has a strictly technical meaning: the definition was changed
> in a way that makes existing code no long work the same way.
> There is no question but that that occurred, and quite late in the
> standardization process, and very little discussion or analysis
> was permitted.

No code was broken by the change according to this definition.
Any code that was legal under the old const rules will have
the same meaning under the new rules. However, some previously
illegal code is now legal.

You could argue that the new rules weakened some existing
designs in that certain guarantees are no longer enforced
by the type system. But it didn't "break" any code.

> >...
> >I wonder, did const really have one particular meaning before
> >C++ was standardized? I looked in the C++ Programming Language
> >second edition (Stroustrup 1991), and I could find no mention
> >of whether deleting a pointer to const is illegal. It seems
> >likely that compilers differed in this respect. If so, any
> >decision the committee made would represent a change to some.
>
> Random speculation sheds no light.  The fact is, compilers were
> consistent on this point.

Ok, serves me right for speculating. Well, at least I
learned something...

> >In any case, we now have a standard, and const _does_ have a
> >particular meaning. To change that meaning at this point would
> >certainly break existing code.
>
> No one proposed changing it.  The issue is the nature of the arguments
> that led to const's breakage.  If you're interested in the failure of
> language standardization processes, you may be interested in this
> topic.  Otherwise, why post?

I guess I missed the thrust of the discussion. I was mainly
interested in whether the current rules make sense (to me they
do), and only marginally interested in the actual process that
led to the current rules.

> >...
> >I agree that it might be nice if you could actually prevent
> >deletion, but I don't think "const" is the best vehicle for
> >this. (You snipped that argument, but it boils down to this:
> >how would you prevent deletion of a non-const pointer?)
>
> Preventing deletion of a non-const pointer is not a feature _ever_
> supported by the language.  It is irrelevant to the issue at hand,
> which is about a change to a real, existing feature.

Obviously this was never a language feature, but it could be.
The current const rules would play very well in the context of
a future C++ language that also had (separate) qualifiers for
restricting deletion. This is relevant to the question of whether
the current const rules are good language design.

I admit it is not relevant to the historical question of
whether the arguments given for changing the const rules were
sound. I didn't realize this was the _only_ issue at hand.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: niklasb@my-deja.com
Date: 1999/09/23
Raw View
In article <slrn7uebbr.ukm.sbnaran@localhost.localdomain>,
  sbnaran@uiuc.edu wrote:
> On 20 Sep 99 23:54:15 GMT, niklasb@my-deja.com <niklasb@my-deja.com>
wrote:
>
> >I agree that it might be nice if you could actually prevent
> >deletion, but I don't think "const" is the best vehicle for
> >this. (You snipped that argument, but it boils down to this:
> >how would you prevent deletion of a non-const pointer?)
>
> My previous post brought up this issue too -- namely, how to
> deal with the general case where we must prevent deleting a
> pointer to non-const.  The last paragraph of my post
> questioned whether we would ever pass a pointer to a
> non-const object to outside clients.  Here it is:
>
> On the other hand, it is rare to pass a pointer to non-const
> House to outside clients, at least in my experience.
> The reason is that when outside clients modify the House the
> class that owns the Houses, namely class List_of_Houses, must
> know of the change so that it can maintain its invariants.
> For example, it may keep the Houses in alphabetical order, or
> it may maintain some sort of internal index (so that if you
> change a House, it must change the index), or maybe it must
> update the field that is the total value of all the houses.
>
> Any thoughts?

Out parameters and in/out parameters are pretty common:

  void Func()
  {
    MyInfo info;
    GetSomeInfo(&info); // non-const pointer
    DoStuff(info);      // const reference
  }

Obviously it would be an error for GetSomeInfo to delete its
argument, but C++ has never had a mechanism for preventing it.


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/20
Raw View
Jeff Rife wrote in message ...
>Anders J. Munch (andersjm@dancontrol.dk) wrote:
>
>> Not necessarily.  Objects created-as-const can be logically viewed as a
>> non-const object being created, except that only const-access is granted
>> under the given name.
>>
>> Programmer writes:
>>     SomeClass const x(initialization);
>
>But, this means that the implementation is free to put the object into
>read-only memory.

Good observation, I missed a nuance here.  The contract introduced with
'const' in the definition is stronger than the contract for a reference
to const.  So my rewrite isn't completely semantically neutral.

This doesn't affect the point I was trying to make, though: That
creating something as const can be viewed as the implementation creating
something non-const and publicizing only const access.  (And this would
apply to *both* constness contracts.)

[...]
>No matter how you word it, the implementation is doing things that are
>out of the reach of the user-code.  Because of that, you can't compare
>what an implementation does behind the scenes to what user-code can do
>in a conforming program.


I wasn't trying to describe implementation.

<formal style=pompous>
What if I demonstrated a way of mechanically transforming any C++
program with well-defined behaviour into a C++ program without any const
objects but with the same behaviour,  in such a way that no ill-defined
C++ program by this transformation became well-defined?
  Ignoring the difference between the two constness contracts, this is
exactly what I did.  And in doing so I have shown that there is no
philosophical problem with the construction and destruction of const
objects, even if deletion of const is disallowed. Q.E.D.
</formal>

- Anders




[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Edward Luke <lush@erc.msstate.edu>
Date: 1999/09/20
Raw View
Francis Glassborow <francis@robinton.demon.co.uk> writes:

> Yes, I think I am coming round to the view that we should consider some
> way of providing a 'may not delete through this pointer/reference'
> property quite distinct from 'may not modify...'


Perhaps, but shouldn't the default be that const implies may not
modify, and then an additional qualifier would be necessary to make it
a deleteable const pointer?

For example,

const X *p ;  // Contents cannot be changed, pointer cannot be deleted
destructable const X *p ; // This pointer can be deleted

This would make the most sense, since most of the time users would
want const to imply that it was not deleteable as well.  However, in
container classes and so on, a destructable pointer could be used in
the internal workings where appropriate.  Thus containers  could work
reasonably with const objects without breaking a rather intuitive
behavior of const.

-Ed

___________________________________________________________________
Ed Luke                                        lush@erc.msstate.edu
NSF Engineering Research Center for Computational Field Simulations
Mississippi State University       http://www.erc.msstate.edu/~lush


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/20
Raw View
On 20 Sep 99 12:57:53 GMT, Francis Glassborow
>In article <slrn7uaduu.pla.sbnaran@localhost.localdomain>, Siemel B.

>>But what about the more general case where we must pass a pointer to
>>non-const House?  Now what's there to prevent clients from delete the
>>pointer?  Nothing.  That's why I'm not convinced that this argument
>>about whether or not we should be able to delete a pointer to const
>>is a useful argument.
>
>Yes, I think I am coming round to the view that we should consider some
>way of providing a 'may not delete through this pointer/reference'
>property quite distinct from 'may not modify...'

Another person suggest
   SomeClass *static s=0;
   deletes; // error

While I like this proposal, one can always write a class static_ptr<> to
achieve the same thing.

--
--------------
siemel b naran
--------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/20
Raw View
In article <qqln1uhmlj8.fsf@Andy.ERC.MsState.Edu>, Edward Luke
<lush@erc.msstate.edu> writes
>Francis Glassborow <francis@robinton.demon.co.uk> writes:
>
>> Yes, I think I am coming round to the view that we should consider some
>> way of providing a 'may not delete through this pointer/reference'
>> property quite distinct from 'may not modify...'
>
>
>Perhaps, but shouldn't the default be that const implies may not
>modify, and then an additional qualifier would be necessary to make it
>a deleteable const pointer?

And I would have preferred a keyword 'implicit' to the one we have
'explicit'.  I would have preferred C to have had an 'export' keyword
rather than its use of static at filescope to hide names etc.  But I am
pragmatic enough to try to change the things I can and not waste energy
on those I cannot.

Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: niklasb@my-deja.com
Date: 1999/09/20
Raw View
In article <37e4a4db$0$221@nntp1.ba.best.com>,
  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>
> <niklasb@my-deja.com> wrote:
> >Whether 'delete pointer-to-const' should be legal is a
> >practical question, the answer to which does not follow
> >inevitably from the internal logic of the language.
>
> Correct.  Engineering consequences matter.

And neither definition of const is inherently more logical
than the other. Nor is either inherently "broken".

> >Phrases like "the decision to break const in the case
> >of delete" therefore frame the question appropriately.
>
> That was how the question was framed when the decision was made.
> "Const" had a particular meaning that affected (myriad) designs,
> and those designs were broken when the meaning was changed.

I wonder, did const really have one particular meaning before
C++ was standardized? I looked in the C++ Programming Language
second edition (Stroustrup 1991), and I could find no mention
of whether deleting a pointer to const is illegal. It seems
likely that compilers differed in this respect. If so, any
decision the committee made would represent a change to some.

In any case, we now have a standard, and const _does_ have a
particular meaning. To change that meaning at this point would
certainly break existing code.

> >I actually think it would be nice if the type system
> >offered some way of declaring a pointer that could not
> >be deleted, but I don't see broadening the definition
> >of const as a very good way to accomplish this.
>
> There is no prospect of "broadening" the definition of const.
> The definition _was_ narrowed.  The arguments that effected its
> narrowing, and how they could have been considered persuasive,
> are the topic.

Well, I agree that there is no real prospect of changing the
definition of const at this point. So what are we doing? Is
the purpose of this discussion merely to analyze the reasoning
behind a decision when the time is long past to do anything
about it?

> >The real issue is with new and delete, not const.
> >Containers and smart pointers make it increasingly
> >possible to use new and delete very sparingly. So if
> >you want to find potentially dangerous code to review
> >carefully, "new" and "delete" might be better
> >candidates for a search than "const_cast".
>
> This is an interesting point: now that const has been broken, our
> coding standards should flag use of "delete" itself as being equally
> as suspicious as "const_cast".  Under the new regime we must wrap
> our pointers up in class objects to get the same protection we had,
> before the breakage, with ordinary pointers.
>
> This is the most succinct description I have seen of the engineering
> consequences of having broken const.

Nice attempt to usurp my argument. But I never attributed
the risks of new and delete to the definition of const. If
you really want to make dynamic allocation safer, the best
thing is to use objects that manage lifetime for you, and
minimize explicit use of new and delete.

I agree that it might be nice if you could actually prevent
deletion, but I don't think "const" is the best vehicle for
this. (You snipped that argument, but it boils down to this:
how would you prevent deletion of a non-const pointer?)


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 1999/09/21
Raw View
Nathan Myers <ncm@nospam.cantrip.org> continues to insult my logic:
> Advancing a logical argument in favor of one's assumptions, based
> on those same assumptions, is logically invalid.

Yes, that would be logically invalid.  Had I done so, you would be right
to complain.

> In all compilers prior to the (quite late) committee decision, const
> had the meaning Ms. Lippincott describes as "further laden".  In other
> words, an important quality of "const" was discarded.

I think this is a slanted view of C++ history.  It is true that ARM
C++ forbade the application of delete to a pointer to const.  And
supports that position with the argument I countered in the posting
Mr. Myers calls "logically invalid."  In this respect, ARM C++
followed Mr Myers position.

On the other hand, ARM C++ allows destructors to be explicitly invoked
on const objects, and allows new to be used to create const objects,
the modification of which produced undefinied behavior.  In these respects,
I believe Mr. Myers position to be unsupported by ARM C++.

In my opinion, the ARM presents a muddled view of the meaning of
const; I see the later committee decision as an attempt to clarify
the meaning.  To my knowledge, there was no draft of C++ that uniformly
supported Mr Myers position.

                                                   --Lisa Lippincott


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jeff Rife <wevsr@nabs.net>
Date: 1999/09/21
Raw View
Anders J. Munch (andersjm@dancontrol.dk) wrote:

> <formal style=pompous>
>
> [snip]
>
>   Ignoring the difference between the two constness contracts, this is
> exactly what I did.  And in doing so I have shown that there is no
> philosophical problem with the construction and destruction of const
> objects, even if deletion of const is disallowed. Q.E.D.
> </formal>

I agree with you on this.  I have never seen a problem with the construction
or destruction of const objects, unlike others on this thread.

As you showed, and I agreed, the compiler is free to do whatever it wants
as long as the behavior that results is correct, because of the AS-IF rule.

--
Jeff Rife                   |
19445 Saint Johnsbury Lane  | http://www.nabs.net/Cartoons/Dilbert/SupportTraining.gif
Germantown, MD  20876-1610  |
Home: 301-916-8131          |
Work: 301-770-5800 Ext 5335 |


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Jeff Rife <wevsr@nabs.net>
Date: 1999/09/21
Raw View
Edward Luke (lush@erc.msstate.edu) wrote:

> For example,
>
> const X *p ;  // Contents cannot be changed, pointer cannot be deleted
> destructable const X *p ; // This pointer can be deleted
>
> This would make the most sense, since most of the time users would
> want const to imply that it was not deleteable as well.

I don't think they would, as there could be a lot of code out there that
breaks by changing the meaning of const in this case.

If you are going to add a keyword, it would be best to makes its meaning
that you *couldn't* delete it, and then only new code would use it, and
old code wouldn't break.

I also think that this keyword construct would have little meaning outside
of the formal parameters of a function.  For example:

indestructible X const *p = new X();

Now, you can never "delete" through p.  The object hangs around until the
end of the program.  This is not really all that good a thing, because you
can achieve the same thing with (outside of any function):

static X x();
static X const * const p = &x;

Now, you certainly can't "delete" through p (well, it's undefined behavior),
and you can't modify x through p, and you can't point p at anything else.

So, since this thread started with complaining about functions with pointers
to const objects being able to delete them, I think we should stick with
that, because it really is the only problem with the current syntax.

--
Jeff Rife                   |
19445 Saint Johnsbury Lane  | http://www.nabs.net/Cartoons/Dilbert/LoveRanking.jpg
Germantown, MD  20876-1610  |
Home: 301-916-8131          |
Work: 301-770-5800 Ext 5335 |


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/21
Raw View
On 20 Sep 99 23:54:15 GMT, niklasb@my-deja.com <niklasb@my-deja.com> wrote:

>I agree that it might be nice if you could actually prevent
>deletion, but I don't think "const" is the best vehicle for
>this. (You snipped that argument, but it boils down to this:
>how would you prevent deletion of a non-const pointer?)

My previous post brought up this issue too -- namely, how to
deal with the general case where we must prevent deleting a
pointer to non-const.  The last paragraph of my post
questioned whether we would ever pass a pointer to a
non-const object to outside clients.  Here it is:

On the other hand, it is rare to pass a pointer to non-const
House to outside clients, at least in my experience.
The reason is that when outside clients modify the House the
class that owns the Houses, namely class List_of_Houses, must
know of the change so that it can maintain its invariants.
For example, it may keep the Houses in alphabetical order, or
it may maintain some sort of internal index (so that if you
change a House, it must change the index), or maybe it must
update the field that is the total value of all the houses.

Any thoughts?

--
--------------
siemel b naran
--------------
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/21
Raw View
<niklasb@my-deja.com> wrote:
>  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>> <niklasb@my-deja.com> wrote:
>> >Whether 'delete pointer-to-const' should be legal is a
>> >practical question, the answer to which does not follow
>> >inevitably from the internal logic of the language.
>>
>> Correct.  Engineering consequences matter.
>
>And neither definition of const is inherently more logical
>than the other. Nor is either inherently "broken".

You cannot decide which is better without analyzing the
consequences of the alternatives.  "Broken", in standardization,
has a strictly technical meaning: the definition was changed
in a way that makes existing code no long work the same way.
There is no question but that that occurred, and quite late in the
standardization process, and very little discussion or analysis
was permitted.

While you cannot decide which is "correct", logically, you can
evaluate arguments logically, and those that advanced in favor
of the breakage have thus far been patent nonsense.

>> >Phrases like "the decision to break const in the case
>> >of delete" therefore frame the question appropriately.
>>
>> That was how the question was framed when the decision was made.
>> "Const" had a particular meaning that affected (myriad) designs,
>> and those designs were broken when the meaning was changed.
>
>I wonder, did const really have one particular meaning before
>C++ was standardized? I looked in the C++ Programming Language
>second edition (Stroustrup 1991), and I could find no mention
>of whether deleting a pointer to const is illegal. It seems
>likely that compilers differed in this respect. If so, any
>decision the committee made would represent a change to some.

Random speculation sheds no light.  The fact is, compilers were
consistent on this point.

>In any case, we now have a standard, and const _does_ have a
>particular meaning. To change that meaning at this point would
>certainly break existing code.

No one proposed changing it.  The issue is the nature of the arguments
that led to const's breakage.  If you're interested in the failure of
language standardization processes, you may be interested in this
topic.  Otherwise, why post?

>> >The real issue is with new and delete, not const.
>> >Containers and smart pointers make it increasingly
>> >possible to use new and delete very sparingly. So if
>> >you want to find potentially dangerous code to review
>> >carefully, "new" and "delete" might be better
>> >candidates for a search than "const_cast".
>>
>> This is an interesting point: now that const has been broken, our
>> coding standards should flag use of "delete" itself as being equally
>> as suspicious as "const_cast".  Under the new regime we must wrap
>> our pointers up in class objects to get the same protection we had,
>> before the breakage, with ordinary pointers.
>>
>> This is the most succinct description I have seen of the engineering
>> consequences of having broken const.
>
>... If you really want to make dynamic allocation safer, the best
>thing is to use objects that manage lifetime for you, and
>minimize explicit use of new and delete.

I have no interest in "making dynamic allocation safer".
Obviously with the language as it is we are obliged to "use
objects to manage lifetime".  This was not necessary before
const was broken.

That people seem to have such difficulty understanding this
consequence, and repeatedly advance irrelevant or specious arguments
to justify the breakage, is the topic of discussion.

>I agree that it might be nice if you could actually prevent
>deletion, but I don't think "const" is the best vehicle for
>this. (You snipped that argument, but it boils down to this:
>how would you prevent deletion of a non-const pointer?)

Preventing deletion of a non-const pointer is not a feature _ever_
supported by the language.  It is irrelevant to the issue at hand,
which is about a change to a real, existing feature.

That this question keeps coming up demonstrates my point, again:
there is something about this issue which seems to prevent some
very smart people from reasoning sensibly.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ark@research.att.com (Andrew Koenig)
Date: 1999/09/21
Raw View
In article <37e7ed42$0$201@nntp1.ba.best.com>,
Nathan Myers <ncm@nospam.cantrip.org> wrote:

>That this question keeps coming up demonstrates my point, again:
>there is something about this issue which seems to prevent some
>very smart people from reasoning sensibly.

I think we can agree on this point, anyway.
--
Andrew Koenig, ark@research.att.com, http://www.research.att.com/info/ark



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/21
Raw View
Bjarne Stroustrup <bs@research.att.com> wrote:
>In the ARM, I'm quite explicit (ARM "5.3.4 Delete" pg 63):
>
> A pointer to constant cannot be deleted. ...
>   The purpose of prohibiting the deletion of pointers to constants
>   is to allow programmers to rely on const objects being immutable.
>       ...
> Naturally, this guarantee - like all other guarantees provided by
> the type system - applies only as long as the type system is not
> deliberately or accidentally broken by explicit type conversion,
> aliasing, compiler errors, or hardware errors.
>
>The committee decided that the advantages of allowing delete for pointers
>to const outweighed the advantages of prohibiting it. There were and are
>reasonable arguments either way. However, we have a standard, the standard
>is clear on this issue, and I think our energies are better spent on other
>issues.

Indeed, inventing increasingly fanciful apologetics for the standard
is a waste of time.  However, understanding how it got that way is
of interest for future language (and other) design efforts.

Thus far no one has advanced any of the "reasonable arguments" that
Bjarne alludes to; if any surface, it might change the nature of
the discussion.  That the unreasonable arguments thus far presented
held sway remains interesting.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/21
Raw View
Andrew Koenig <ark@research.att.com> wrote:
>Nathan Myers <ncm@nospam.cantrip.org> wrote:
>
>>This is just Koenig's latest argument, again: because the language
>>(still) lacks feature Y (a pointer type that allows non-const member
>>access but prevents deletion), it was good to break the more-frequently
>>useful, and long-established, feature X (a safer pointer type that
>>prevents both non-const member access and deletion).
>
>You have misstated my argument, so I shall have to repeat it again.

It would be more useful to respond to comments, rather than
simply to repeat the same arguments again.

>There is a choice between two features: the ability to guarantee
>that a function will not delete an object the address of which is
>given to it, and the ability of a program to delete the objects
>that it allocates.

The "choice between two features" was not the choice voted on in
committee, and it is not a choice under discussion here.  The choice
voted on in committee was whether to break const semantics.  The
committee chose "yes" based on arguments presented which have been
demonstrated to be specious.  Additional arguments have since been
advanced, also demonstrated to be specious.  Thus far we have seen
(summarizing):

  analogy to auto objects (irrelevant to the question)
  analogy to Unix permissions (invalid analogy)
  template can't delete T (demonstrated otherwise)
  want containers of const T (still illegal)
  language lacks non-const no-delete feature (irrelevant)

and now

  const wasn't useful anyway

Koenig has never defended his arguments; he has simply repeated the
same arguments after a suitable interval.

>It is not possible to have both these features at once, so it
>is necessary to choose between them.

In fact, we _had_ both features at once, once.   The committee simply
abolished one of them, based on what has already been demonstrated
as specious reasoning.  Since then many more examples of specious
reasoning have been advanced in apology for the breakage.

>Closer examination reveals that a function that takes a pointer to
>const as its argument might delete the object anyway, because it
>can use a cast to remove the const.  Hence the ``guarantee'' is no
>guarantee at all.   Moreover, even if it were, it is of only limited
>utility, because it covers only a secondary case (where the object
>is also not modified) and ignores the primary case (where the object
>can be modified but not deleted).

Andrew's choice of "primary" and "secondary" is pure invention.
In fact, the use of const in interfaces was to protect against _any_
violation of invariants, including modification and deletion.
Clearly, splitting these out would be a refinement, but (if you will)
a "secondary" one.

>I therefore believe that ``feature X'' is not useful, and indeed
>has never existed in the form that would appear to be true at
>first glance.

"Const" had a specific meaning.  That meaning was, in fact, broken.
If type-safety features are useful only where casting cannot bypass
them, then no type-safety feature is useful at all, because a cast
can appear anywhere.

Type-safety as a tool in interface design is necessarily discussed
assuming a coding-standard restriction against routine casting.
However, coding standards don't define the language, they only
describe a safe use of the language.  Uses outside a coding standard
can also be proven safe, so casts remain a useful part of the language
for implementing interfaces.  (Andrew understands this.)

Therefore, the language always supported both pointer-to-const as
a way to protect interface invariants, and also allowed deletion
of such a pointer through the use of casting -- or by maintaining a
non-const copy of the pointer.

>Closer examination also reveals that if the language does not allow
>programs to delete the objects that they allocate, it is possible
>to fudge around the restriction.  However, it is not clear whether
>the language definition actually allows that fudging, and the way to
>accomplish it is far from easy to understand.

In fact, the language _always_ allowed programs to delete all objects
they allocated.  If Andrew knows of any case where it may not have
allowed it, he should identify it.  (Every example he has advanced
thus far has been eliminated, although he has never acknowledged it.)

If by "fudging", Andrew refers to the legality of casting away const
on a pointer returned by "new const T", I remind the reader that the
equivalence between "new const T" and "new T" was broken *after*
const itself was broken.  (This has been noted before in this forum.)

>I think it is entirely legitimate for anyone to disagree with me on
>this issue who extends the reciprocal courtesy.

No one needs Andrew's permission to disagree with him, magnanimous as
it is of him to offer it.

At issue here is the long series of specious arguments in support of
breaking an existing, and heavily used, language feature.  Discussion
of an imaginary non-feature has only served to distract readers.

It doesn't matter whether one "agrees" or "disagrees" with Andrew: the
topic raised was why people even as smart as Andrew consider(ed?) the
ill-supported arguments mentioned above persuasive.

What would be useful for Andrew (or somebody else) to extend would
not be permission to disagree, nor a bald restating of previous
assertions, but an introspective explanation of how such intelligent
people allowed themselves to be misled by such arguments.

Again, it doesn't matter whether breaking const was right or wrong:
the standard is what it is.  It does matter that "what it is" resulted
from nonsensical arguments, because we should be equipped to recognize
when a design issue arises which derails intelligent individuals'
reasoning skills this way.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/22
Raw View
niklasb@my-deja.com () wrote:
> I wonder, did const really have one particular meaning before
> C++ was standardized? I looked in the C++ Programming Language
> second edition (Stroustrup 1991), and I could find no mention
> of whether deleting a pointer to const is illegal.

See the Annotated Reference Manual, $5.3.4 "Delete", "A pointer to
constant cannot be deleted". There is an excellent explanation of why this
is necessary in the commentary. It's not a grey area.


> It seems likely that compilers differed in this respect. If so, any
> decision the committee made would represent a change to some.

It doesn't seem very likely to me. The ARM was the closest thing we had to
a formal standard until the standard itself appeared. It is remarkable
that the committee decided to reverse an ARM rule.


> Well, I agree that there is no real prospect of changing the
> definition of const at this point. So what are we doing? Is
> the purpose of this discussion merely to analyze the reasoning
> behind a decision when the time is long past to do anything
> about it?

We have to decide what to tell the children.

Generally some newbie comes across the rule, is puzzled, and asks for a
justification. That is why the discussion recurs here every 6 months. If
we made a mistake, it's best to be honest about it rather than try to
justify a bad rule.

Also there are things we can do for the future. One is to publicly deplore
the practice of deleting const pointers. Another is to encourage compiler
vendors to issue warnings when it happens. If we agree to start doing
these things now, perhaps in 5 years we can get the standard changed.
Bigger changes have been made in the past.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/22
Raw View
In article <37e809ab$0$209@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>Again, it doesn't matter whether breaking const was right or wrong:
>the standard is what it is.  It does matter that "what it is" resulted
>from nonsensical arguments, because we should be equipped to recognize
>when a design issue arises which derails intelligent individuals'
>reasoning skills this way.

Nathan, much as respect your technical expertise and your frustration
that otherwise intelligent people seem unable to agree with you, I have
been increasingly unhappy with your choice of adjectives that seek to
denigrate your opponents arguments.  This is not a formal debate where
you are allowed to score points this way.



Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/22
Raw View
In article <37e80d1e$0$206@nntp1.ba.best.com>, Nathan Myers
<ncm@nospam.cantrip.org> writes
>Thus far no one has advanced any of the "reasonable arguments" that
>Bjarne alludes to; if any surface, it might change the nature of
>the discussion.  That the unreasonable arguments thus far presented
>held sway remains interesting.

Perhaps reasonable is in the eye of the beholder ;-)


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/19
Raw View
<niklasb@my-deja.com> wrote:
>Whether 'delete pointer-to-const' should be legal is a
>practical question, the answer to which does not follow
>inevitably from the internal logic of the language.

Correct.  Engineering consequences matter.

>Phrases like "the decision to break const in the case
>of delete" therefore frame the question appropriately.

That was how the question was framed when the decision was made.
"Const" had a particular meaning that affected (myriad) designs,
and those designs were broken when the meaning was changed.

>I actually think it would be nice if the type system
>offered some way of declaring a pointer that could not
>be deleted, but I don't see broadening the definition
>of const as a very good way to accomplish this.

There is no prospect of "broadening" the definition of const.
The definition _was_ narrowed.  The arguments that effected its
narrowing, and how they could have been considered persuasive,
are the topic.

>The real issue is with new and delete, not const.
>Containers and smart pointers make it increasingly
>possible to use new and delete very sparingly. So if
>you want to find potentially dangerous code to review
>carefully, "new" and "delete" might be better
>candidates for a search than "const_cast".

This is an interesting point: now that const has been broken, our
coding standards should flag use of "delete" itself as being equally
as suspicious as "const_cast".  Under the new regime we must wrap
our pointers up in class objects to get the same protection we had,
before the breakage, with ordinary pointers.

This is the most succinct description I have seen of the engineering
consequences of having broken const.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/19
Raw View
Lisa Lippincott  <lisa_lippincott@bigfix.com> wrote:
>Nathan Myers <ncm@nospam.cantrip.org>
>> The decision to break const for the case of delete-expressions may turn
>> out to be a minor wart in the language.  What is far worse, in my view,
>> is the breakdown in logical reasoning processes it seems to bring
>> repeatedly to the surface.  Lippincott's attempt at argument by begging
>> the question was far from the first, and probably will not be the last,
>> that we have seen here.
>>
>> What is it about this issue that leads people to advance arguments so
>> clearly stated, but logically bankrupt?
>
>As an accredited logician, I take exception to this reproach.
>
>I suggest that, should you examine my argument in a less heated mood,
>you will find its logic sound.  The argument does, however, rest on two
>nonlogical assumptions, with which you are free to disagree.

It is, specifically, the assumptions that are under discussion.

Advancing a logical argument in favor of one's assumptions, based
on those same assumptions, is logically invalid.

>As a practical matter, he would rather have const mean "may not be
>modified, and may not have its lifetime ended explicitly." With this
>opinion I respectfully disagree; the meaning of const should not
>be further laden.

In all compilers prior to the (quite late) committee decision, const
had the meaning Ms. Lippincott describes as "further laden".  In other
words, an important quality of "const" was discarded.  It was discarded
based on unsound reasoning -- argument by analogy, as it happened.

Subsequently, apologists have advanced increasingly sophistic arguments
why breaking const was good, in every case arguing without reference to
engineering consequences.



Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/19
Raw View
Siemel B. Naran <sbnaran@uiuc.edu> wrote:
>On 15 Sep 1999 19:09:09 GMT, niklasb@my-deja.com <niklasb@my-deja.com> wrote:
>
>>Whether 'delete pointer-to-const' should be legal is a
>>practical question, the answer to which does not follow
>>inevitably from the internal logic of the language.
>
>...  Can anyone think of a practical reason why
>being able to delete a pointer to const is a bad thing?

Elementary.  The argument does depend on some familiarity with
library design.

Imagine you are designing a library which maintains an internal object
of a public type.  Prior to the breakage of const it was perfectly safe
for the library to hand a pointer to this object off to an (untrusted)
client of the library, because a pointer-to-const was inviolate.  A
client was _incapable_ of violating any of the library's invariants
(except, as usual, by casting).

Now, to get the same level of safety you must define a wrapper class,
with forwarding functions, and release only instances of this wrapper
class.

What important language feature did we get in exchange for this pervasive
increase in complexity of libraries?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/20
Raw View
On 19 Sep 1999 15:33:43 GMT, Nathan Myers <ncm@nospam.cantrip.org> wrote:
>Siemel B. Naran <sbnaran@uiuc.edu> wrote:

>>...  Can anyone think of a practical reason why
>>being able to delete a pointer to const is a bad thing?
>
>Elementary.  The argument does depend on some familiarity with
>library design.
>
>Imagine you are designing a library which maintains an internal object
>of a public type.  Prior to the breakage of const it was perfectly safe
>for the library to hand a pointer to this object off to an (untrusted)
>client of the library, because a pointer-to-const was inviolate.  A
>client was _incapable_ of violating any of the library's invariants
>(except, as usual, by casting).

I think my example of a function returning a container<House const *>
was such an example.  The function, usually a member of class
List_of_Houses, passes houses to other clients for them to look at.
The const is an assurance that these other clients won't be able to
delete these House pointers.

But what about the more general case where we must pass a pointer to
non-const House?  Now what's there to prevent clients from delete the
pointer?  Nothing.  That's why I'm not convinced that this argument
about whether or not we should be able to delete a pointer to const
is a useful argument.

On the other hand, it is rare to pass a pointer to non-const House
to outside clients, at least in my experience.  The reason is that
when outside clients modify the House the class that owns the
Houses, namely class List_of_Houses, must know of the change so
that it can maintain its invariants.  For example, it may keep the
Houses in alphabetical order, or it may maintain some sort of
internal index (so that if you change a House, it must change the
index), or maybe it must update the field that is the total value
of all the houses.


>Now, to get the same level of safety you must define a wrapper class,
>with forwarding functions, and release only instances of this wrapper
>class.

I think we need write only an operator-> and operator*.  I posted a
class static_ptr in a previous post.


>What important language feature did we get in exchange for this pervasive
>increase in complexity of libraries?

--
--------------
siemel b naran
--------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/20
Raw View
Siemel B. Naran <sbnaran@uiuc.edu> wrote:
>Nathan Myers <ncm@nospam.cantrip.org> wrote:
>>Siemel B. Naran <sbnaran@uiuc.edu> wrote:
>
>>>...  Can anyone think of a practical reason why
>>>being able to delete a pointer to const is a bad thing?
>>
>>Elementary.  The argument does depend on some familiarity with
>>library design.
>>
>>Imagine you are designing a library which maintains an internal object
>>of a public type.  Prior to the breakage of const it was perfectly safe
>>for the library to hand a pointer to this object off to an (untrusted)
>>client of the library, because a pointer-to-const was inviolate.  A
>>client was _incapable_ of violating any of the library's invariants
>>(except, as usual, by casting).
>
>I think my example of a function returning a container<House const *>
>was such an example. ...
>But what about the more general case where we must pass a pointer to
>non-const House?  Now what's there to prevent clients from delete the
>pointer?  Nothing.  That's why I'm not convinced that this argument
>about whether or not we should be able to delete a pointer to const
>is a useful argument.

This is just Koenig's latest argument, again: because the language
(still) lacks feature Y (a pointer type that allows non-const member
access but prevents deletion), it was good to break the more-frequently
useful, and long-established, feature X (a safer pointer type that
prevents both non-const member access and deletion).

Let's try it this argument in another quarter: C++ lacks the
"long long" type introduced into C0x.  Therefore, we should make
the effect of arithmetic overflow on unsigned int undefined.
After all, if we don't support "long long", why help users to
code it themselves?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/20
Raw View
In article <slrn7uaduu.pla.sbnaran@localhost.localdomain>, Siemel B.
Naran <sbnaran@uiuc.edu> writes
>But what about the more general case where we must pass a pointer to
>non-const House?  Now what's there to prevent clients from delete the
>pointer?  Nothing.  That's why I'm not convinced that this argument
>about whether or not we should be able to delete a pointer to const
>is a useful argument.

Yes, I think I am coming round to the view that we should consider some
way of providing a 'may not delete through this pointer/reference'
property quite distinct from 'may not modify...'


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jerry Leichter <jerrold.leichter@smarts.com>
Date: 1999/09/17
Raw View
| Consider the sequence of steps involved in creating an object.
|
|    First, storage is obtained;
|    second, subobjects are constructed;
|    third, the body of the constructor is executed;
|    finally, the lifetime of the object begins.  If the object is
| const, it may not be modified.
|
| It's pretty hard to argue for a different arrangement.  Does anyone
| want to try?

"Lifetime" as generally used in discussing programming languages begins
as soon as the storage is allocated.  That stack allocation works for
locals in "Algol-like" languages is generally explained by saying that
in this arrangement a variable's lifetime is the same as its scope.

C++ differs from most languages by having user-written constructors.
It's certainly the case that a variable is in *some* special state
between the time its storage is obtained and the time that its
constructor returns, but I see no reason to say that its lifetime has
not begun.  If you *do* say that, how do you describe what "this" refers
to in a member function called from a constructor?  It's one thing to
say that *constructors* operate on variables before their lifetimes
begin, but do you really want to say that a member function can be
called on an object outside of that object's lifetime?

| Most people will also agree that the demolition of an object should
| reverse the creation.  Thus:
|
|    First, the lifetime of the object ends;
|    second, the body of the destructor is executed;
|    third, subobjects are destroyed;
|    finally, storage is released.
|
| Looking at this chronology, it's clear that the destructor does not
| operate on the object -- instead, it operates on the subobjects.  The
| question of whether the former object was const is moot.

The same question arises here:  It's perfectly OK for a destructor to
call member functions.  If the destructor only operates on subobjects,
does that mean member functions it calls only operates on subobjects?
Does what a member function "operates on" depend on where the function
was called?

Hell, you don't even have to restrict yourself to member functions!  A
constructor or destructor is perfectly free to pass "this" to any
function that takes an argument of the appropriate type.  If a
constructor does this as the last statement in its body - or a
destructor does it as the first statement in its body - then in fact the
object is guaranteed to be in a fully constructed state (for its type) -
so this is as safe and correct as passing any other object of the
appropriate type.  Are you saying any function in the program can
operate on objects "after their lifetime"?  If so, your definition of
"lifetime" is more than a bit strange!
       -- Jerry


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: James Kuyper <kuyper@wizard.net>
Date: 1999/09/17
Raw View
Jerry Leichter wrote:
...
> "Lifetime" as generally used in discussing programming languages begins
> as soon as the storage is allocated.  That stack allocation works for
> locals in "Algol-like" languages is generally explained by saying that
> in this arrangement a variable's lifetime is the same as its scope.

Irrelevant - the standard defines "lifetime", and that isn't the
definition it uses.

> C++ differs from most languages by having user-written constructors.
> It's certainly the case that a variable is in *some* special state
> between the time its storage is obtained and the time that its
> constructor returns, but I see no reason to say that its lifetime has
> not begun.

The rules about 'lifetime' were designed to cope with the
characteristics of fully constructed objects that have not yet started
being destroyed; it really doesn't matter what you call that period of
time - those rules are still needed.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 1999/09/16
Raw View
Anders J. Munch <andersjm@dancontrol.dk> wrote:
> Before destruction: If the complete object was const, then all the
> subobjects were also const.
>
> Destruction initiated: Complete object doesn't exist as such, however
> subobjects still exist.  As they still exist, the const property still
> applies to them.

No, they were const only by virtue of being members of a const object.
Upon entry into the destructor, they are no longer members of any object.
Those which were not declared const are no longer const.

I think that's a straightforward reading of 3.9.3 [basic.type.qualifier].
One could image it being written otherwise, but it would make const
objects awfully hard to construct.

                                                   --Lisa Lippincott


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/17
Raw View
Lisa Lippincott wrote in message
<160919991230311725%lisa_lippincott@bigfix.com>...
>
>Anders J. Munch <andersjm@dancontrol.dk> wrote:
>> Before destruction: If the complete object was const, then all the
>> subobjects were also const.
>>
>> Destruction initiated: Complete object doesn't exist as such, however
>> subobjects still exist.  As they still exist, the const property
still
>> applies to them.
>
>No, they were const only by virtue of being members of a const object.
>Upon entry into the destructor, they are no longer members of any
object.
>Those which were not declared const are no longer const.

Constness in function arguments is a contract between caller and callee,
and we are debating whether this contract allows destruction.  Agreed?

Which one of the functions f1 and f2 below has the strictest contract?

struct S1
{
    int const aMem;
    ~S1();
};

struct S2
{
    int aMem;
    ~S2();
};

void f1(S1&);
void f2(S2 const &);


I would say that f2 should have the stricter contract, because here
constness applies to the complete object, whereas with f1 constness
applies only the member
aMem.

But with your semantics, f2 has a more lenient contract, because when
~S2() is invoked, aMem can be assigned to.

>I think that's a straightforward reading of 3.9.3
[basic.type.qualifier].
>One could image it being written otherwise, but it would make const
>objects awfully hard to construct.


Not necessarily.  Objects created-as-const can be logically viewed as a
non-const object being created, except that only const-access is granted
under the given name.

Programmer writes:
    SomeClass const x(initialization);

Compiler internally rewrites this into:
    SomeClass __shadow_x(initialization);
    SomeClass const & x = __shadow_x;

Under this view, const objects are never actually created or destroyed.

- Anders
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Jeff Rife <wevsr@nabs.net>
Date: 1999/09/17
Raw View
Anders J. Munch (andersjm@dancontrol.dk) wrote:

> Not necessarily.  Objects created-as-const can be logically viewed as a
> non-const object being created, except that only const-access is granted
> under the given name.
>
> Programmer writes:
>     SomeClass const x(initialization);

But, this means that the implementation is free to put the object into
read-only memory.  I know, it has to be writable to put it there, but by
changing processor protection on the memory area, many implementations
could do this, so by the time the rest of the user progam sees it, it
is in read-only memory.

This is entirely different from something like:

void func(SomeClass const * x)
{
SomeClass* y = const_cast<SomeClass*>(x);

y->Fred = 7;
}

Here, the compiler *cannot* assume that the object pointed to is actually
const.  The function above *does* not invoke undefined behavior if
the object pointed to by x is not actually const like:

SomeClass z;
func(&z);

The const contract in the function declaration is being violated, and we
all agree that this is horrible programming, but it is legal, as long
as it is never called with an actual const object being pointed to.

> Compiler internally rewrites this into:
>     SomeClass __shadow_x(initialization);
>     SomeClass const & x = __shadow_x;
>
> Under this view, const objects are never actually created or destroyed.

Using the read-only-memory idea above, const objects are neither created
or destroyed, either.  The implmentation creates an object, puts it in
a place that makes it const to the rest of the user-code, and eventually
destroys it there.

No matter how you word it, the implementation is doing things that are
out of the reach of the user-code.  Because of that, you can't compare
what an implementation does behind the scenes to what user-code can do
in a conforming program.

--
Jeff Rife                   | Making files is easy under the UNIX operating
19445 Saint Johnsbury Lane  | system.  Therefore, users tend to create numerous
Germantown, MD  20876-1610  | files using large amounts of file space. It has
Home: 301-916-8131          | been said that the only standard thing about all
Work: 301-770-5800 Ext 5335 | UNIX systems is the message-of-the-day telling
                            | users to clean up their files.
                            |              -- System V.2 administrator's guide
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/17
Raw View
Lisa Lippincott wrote in message
<150919991344231146%lisa_lippincott@bigfix.com>...
>James Kanze <James.Kanze@dresdner-bank.com> wrote:

[...]
>> I'd be interested in seeing a *real* example where allowing it helps.
[...]
>Consider auto_ptr.  In my view, disallowing deletion of const objects
>would require a specialization of auto_ptr for const types, and I'm not
>even sure how to write that specialization.

[...]

The question was: Why would you want to delete a pointer to something
const?

Since auto_ptr is simply a way of automating the delete process, this is
just forwarding the issue.

New question: Why would you want to create an auto_ptr to something
const?

Same question in a different guise.

- Anders



[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 1999/09/15
Raw View
Nathan Myers <ncm@nospam.cantrip.org> raises my dander:
> The decision to break const for the case of delete-expressions may turn
> out to be a minor wart in the language.  What is far worse, in my view,
> is the breakdown in logical reasoning processes it seems to bring
> repeatedly to the surface.  Lippincott's attempt at argument by begging
> the question was far from the first, and probably will not be the last,
> that we have seen here.
>
> What is it about this issue that leads people to advance arguments so
> clearly stated, but logically bankrupt?

As an accredited logician, I take exception to this reproach.

I suggest that, should you examine my argument in a less heated mood,
you will find its logic sound.  The argument does, however, rest on two
nonlogical assumptions, with which you are free to disagree.

The first assumption is that the current rules defining object lifetime
are well-chosen.  As they apply to the matter at hand, I think they are,
and I've seen no argument to the contrary here.

The second, and perhaps more controversial, assumption is that the meaning
we wish to ascribe to const is simply "a const object may not be modified."

Others -- though notably not Mr. Myers -- have argued that executing an
object's destructor modifies the object, and that the second assumption
therefore forbids deleting a const object.  I earned Mr. Myers's scorn
by pointing out the flaw in this argument: that it relies on the ill-defined
notion of modifying an object which no longer exists.

On the other hand, it is my impression that Mr. Myers simply rejects the
second assumption.  As a practical matter, he would rather have const
mean "may not be modified, and may not have its lifetime ended explicitly."
With this opinion I respectfully disagree; the meaning of const should not
be further laden.  Further, I disdain his repeated suggestion that all
arguments contrary to his opinion are illogical.

                                                   --Lisa Lippincott
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: James.Kanze@dresdner-bank.com
Date: 1999/09/15
Raw View
In article <37dde728$0$231@nntp1.ba.best.com>,
  ncm@nospam.cantrip.org (Nathan Myers) wrote:

> >The usual argument against it is that when the destructor is called,
> >the object is still const. This argument ignores the inherent
> >symmetry between constructor and destructor.

> Again, purely theoretical arguments, e.g. about "symmetry", fail
> to consider engineering consequences.  You can make up arguments
> to support anything at all if you carefully avoid discussing
> consequences.

Andy Koenigs long posting pretty much convinced me that the theory
supported allowing delete on const objects.  But if theoretical concerns
had affected the definition of C++, it would be a far different
language.  C++ has always come down on the pragmatic, getting things
done, side.  And on this side, my experience strongly suggests that
allowing deletion of const objects removes a certain number of very
useful compile time checks, without giving any real practical advantages
in return.  As Nathan says, the engineering consequences favor
forbidding it.

I'd be interested in seeing a *real* example where allowing it helps.
The template examples are interesting, but from this point of view, only
valid if you can show me a real template which would really be
instantiated on a const type -- off hand, I can't think of one.

> >>What is it about this issue that leads people to advance arguments
> >>so clearly stated, but logically bankrupt?

> >As long as people on this list (some, unlike me, with lots of
> >credentials behind them) continue to invest in this particular
> >venture, I would not consider their position `bankrupt'.

> The expression "good money after bad" comes to mind.  Those who
> argued in committee for breaking const have an emotional investment
> in the breakage.  Advancing logically-unsound arguments in its
> favor, and failing to respond to demonstrations that it was a
> serious mistake, are the nature of the continued investment.

This is coming very close to an ad hominum argument -- I'm surprised
that the moderators let it through.  I think Andy is 100% sincere in his
position; you can speculate as to hidden psycological motivations, but
this forum is not the place for it (and probably neither you nor I are
really trained for it either).

--
James Kanze                   mailto: James.Kanze@dresdner-bank.com
Conseils en informatique orient   e objet/
                  Beratung in objekt orientierter Datenverarbeitung
Ziegelh   ttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: zivca@netvision.net.il (Ziv Caspi)
Date: 1999/09/15
Raw View
On 14 Sep 99 10:31:09 GMT, ncm@nospam.cantrip.org (Nathan Myers)
wrote:

>Ziv Caspi <zivca@netvision.net.il> wrote:
>>ncm@nospam.cantrip.org (Nathan Myers) wrote:
>>>Lisa Lippincott  <lisa_lippincott@advisories.com> wrote:
>>>>...  it's clear that the destructor does not
>>>>operate on the object -- instead, it operates on the subobjects.  The
>>>>question of whether the former object was const is moot.
>>>>
>>>>So there is no sense in which destruction or deletion is a non-const
>>>>operation.
>>
>>>
>>> ... once the destructor is entered the question of const or non-const
>>>is moot.  However, the question was of who should be allowed to cause
>>>the destructor to be entered.  Thus, Lippincott's argument purely begs
>>>the question.
>>
>>It also answers it. By symmetry, whoever gets to call the constructor
>>for const objects also gets the right to call its destructor.
>
>To beg the question is to _fail_ to answer it.  You may assume the
>conclusion only if use it to show a contradiction in arguments for it.
>You cannot support a conclusion by assuming it.  This is elementary.

1. Lippincott's argument was based on (mirror) symmetry between
  the constructor and destructor. Although it did not directly address
  the issue you raised, extending the argument to cover it is a
  trivial effort (regardless of whether you think it is true or not).
  That's why I said "it also answers it". Isn't it you who like to
  say "fill in the blanks"?

2. Rereading your answer, I don't believe you addressed the issue
  I raised.

>
>>The usual argument against it is that when the destructor is called,
>>the object is still const. This argument ignores the inherent symmetry
>>between constructor and destructor.
>
>Again, purely theoretical arguments, e.g. about "symmetry", fail
>to consider engineering consequences.  You can make up arguments
>to support anything at all if you carefully avoid discussing
>consequences.
>
>>>What is it about this issue that leads people to advance arguments so
>>>clearly stated, but logically bankrupt?
>>
>>As long as people on this list (some, unlike me, with lots of
>>credentials behind them) continue to invest in this particular
>>venture, I would not consider their position `bankrupt'.
>
>The expression "good money after bad" comes to mind. Those who
>argued in committee for breaking const have an emotional investment
>in the breakage.  Advancing logically-unsound arguments in its
>favor, and failing to respond to demonstrations that it was a
>serious mistake, are the nature of the continued investment.

Perhaps. On the other hand, the "demonstrations" you mention
failed to convince several people, including myself. Perhaps
it is because we are all "silly". Then again, perhaps not. Is that
why you have not addressed any of my arguments?

---------------------------------------------
Ziv Caspi
zivca@netvision.net.il


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: niklasb@my-deja.com
Date: 1999/09/15
Raw View
In article <9W06JmAItl33Ewri@robinton.demon.co.uk>,
  Francis Glassborow <francisG@robinton.demon.co.uk> wrote:
>
> In article <7rjh8g$2mv$1@nnrp1.deja.com>, niklasb@my-deja.com writes
> >But if you
> >change a thing, you should be able to inspect it before and after
> >and find some difference; you cannot inspect an object that has
> >been deleted. You might say you changed the object's 'existence',
> >but this is not an attribute of the object. If an object had an
> >'existence' attribute it would always be true, for you cannot
> >refer at all to a non-existent object. Whether a particular object
> >exists or not is not part of the state of that object, but a fact
> >about the state of the program as a whole.
>
> In a reference counted object it is perfectly reasonable to require that
> the object data is not changed while allowing its reference count
> (presumably mutable) to be lowered by one.  In such cases it is possible
> to delete an object and examine the data afterwards.

You can _dereference_ an object and examine it afterwards
(if it has not been deleted), but it is never possible to
_delete_ an object and examine it afterwards. Reference
counting does not change the meaning of delete; it is
merely one mechanism for determining when deletion occurs.

Whether 'delete pointer-to-const' should be legal is a
practical question, the answer to which does not follow
inevitably from the internal logic of the language.
Phrases like "the decision to break const in the case
of delete" therefore frame the question appropriately.

I actually think it would be nice if the type system
offered some way of declaring a pointer that could not
be deleted, but I don't see broadening the definition
of const as a very good way to accomplish this. In my
experience, constness simply doesn't correlate very
well with whether a pointer should be "deletable". If
anything, delete permission should be controlled by a
separate type qualifier, something like this:

  T* new p1;    // 'delete p1' is ok
  T* new[] p2;  // 'delete[] p2' is ok
  T* static p3; // can't delete p3
  T* p4;        // no restrictions

The real issue is with new and delete, not const.
Containers and smart pointers make it increasingly
possible to use new and delete very sparingly. So if
you want to find potentially dangerous code to review
carefully, "new" and "delete" might be better
candidates for a search than "const_cast".


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Lisa Lippincott <lisa_lippincott@bigfix.com>
Date: 1999/09/16
Raw View
James Kanze <James.Kanze@dresdner-bank.com> wrote:
> And on this side, my experience strongly suggests that
> allowing deletion of const objects removes a certain number of very
> useful compile time checks, without giving any real practical advantages
> in return.  As Nathan says, the engineering consequences favor
> forbidding it.
>
> I'd be interested in seeing a *real* example where allowing it helps.
> The template examples are interesting, but from this point of view, only
> valid if you can show me a real template which would really be
> instantiated on a const type -- off hand, I can't think of one.

Consider auto_ptr.  In my view, disallowing deletion of const objects
would require a specialization of auto_ptr for const types, and I'm not
even sure how to write that specialization.

On the other hand, if there were a separate cv-qualifier denoting the
ability to delete an object, its use would greatly clarify the interface
to auto_ptr for both const and non-const types.

                                                   --Lisa Lippincott
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: "Anders J. Munch" <andersjm@dancontrol.dk>
Date: 1999/09/16
Raw View
Lisa Lippincott wrote in message
<090919992359200362%lisa_lippincott@advisories.com>...
[...]
>Looking at this chronology, it's clear that the destructor does not
>operate on the object -- instead, it operates on the subobjects.  The
>question of whether the former object was const is moot.

>
>So there is no sense in which destruction or deletion is a non-const
>operation.


I'll concede that, let's take a look at the consequences:

Before destruction: If the complete object was const, then all the
subobjects were also const.

Destruction initiated: Complete object doesn't exist as such, however
subobjects still exist.  As they still exist, the const property still
applies to them.

This means that destructors must satisfy the requirements of a const member
function - all non-mutable members considered const etc.

Since the destructor may be implemented elsewhere without satisfying this
requirement, it simply cannot be fulfilled.  In short: delete cannot be
invoked on a const object.

- Anders





[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: sbnaran@uiuc.edu (Siemel B. Naran)
Date: 1999/09/16
Raw View
On 15 Sep 1999 19:09:09 GMT, niklasb@my-deja.com <niklasb@my-deja.com> wrote:

>Whether 'delete pointer-to-const' should be legal is a
>practical question, the answer to which does not follow
>inevitably from the internal logic of the language.

It seems to me that the decisions to allow or disallow
deleting a pointer to const are both equally logical.

>Phrases like "the decision to break const in the case
>of delete" therefore frame the question appropriately.

Agreed.  Can anyone think of a practical reason why
being able to delete a pointer to const is a bad thing?

My original thought was that if I make a container of
pointers to existing objects like
   std::deque<House const *> expensive_houses(const std::list<House>&);
then the 'const' would garauntee that no-one
accidentally deletes any houses.

But I soon realized that I want the same restriction
for pointers to non-const object.
   std::deque<House *> expensive_houses(const std::list<House>&);
Still, users should not be able to delete houses in
the deque.



>  T* new p1;    // 'delete p1' is ok
>  T* new[] p2;  // 'delete[] p2' is ok
>  T* static p3; // can't delete p3
>  T* p4;        // no restrictions

This is a great idea.
There is additional work for the compiler to do, but no runtime overhead.
There are some conversion rules, like "T *new" to "T *static" is ok, but
"T *static" to "T *new" is not.

   // find all houses that are expensive
   std::deque<House *static> expensive_houses(const std::list<House>&);

However, these extensions are not necessary because one can write
almost-smart pointer classes to do the same, although it would be
nice to have these almost-smart pointer classes standardized.

   // find all houses that are expensive
   std::deque<static_ptr<House>> expensive_houses(const std::list<House>&);


where

   template <class T>
   class static_ptr {
      public:
         explicit static_ptr(T * ptr) : ptr(ptr) { }
         T * operator->() const { return ptr; }
      private:
         T * ptr;
   };


--
--------------
siemel b naran
--------------


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: scorp@btinternet.com (Dave Harris)
Date: 1999/09/16
Raw View
lisa_lippincott@bigfix.com (Lisa Lippincott) wrote:
> Consider auto_ptr.  In my view, disallowing deletion of const objects
> would require a specialization of auto_ptr for const types, and I'm not
> even sure how to write that specialization.

Auto_ptr is intended to delete objects, and if we're agreed that const
types may not be deleted then it doesn't make sense to instantiate
auto_ptr for them. To do so would introduce a type error. It should be
disallowed by default.

For example:

    void proc1( const int *p ) {
        std::auto_ptr<const int> pp( p );

    } // *p deleted here?

attempts to do exactly what we want proc's signature to forbid. Please
don't add a specialisation of auto_ptr which makes this silently work.

Consider instead adding a const_auto_ptr which uses <type> instead of
<const type>, but which adds const to the type in its public methods. It
would allow you to write:

    void test() {
        const_auto_ptr<int> p( new int( 42 ) );
        proc2( p );
    }

    void proc2( const_auto_ptr<int> p ) {
        // *p = 99; -- would be a compile error; *p is const.

    } // but *p is deleted here

const_auto_ptr<> is trivial to write and allows you to express what is
needed in a type-safe way. We can also write wrappers which make the
deletion optional to express what Andrew Koenig called "const but
dynamic", his "f3" signature.

Obviously we can do the other thing; with the current rules we can produce
a wrapper which exposes its object as const but not deletable. Functions
like proc1() could use it to promise non-deletion. Of course they could
never take its address or pass it to another function except in its
non-delete wrapper. The idiom would be incompatible with existing code.
Still, advocates of the old ARM rule should consider this if they think
non-deletability is so important.

With the right wrappers we can express almost anything, so we're really
talking about what the default should be. This comes down to two
questions:

1) Which would be most commonly needed?
2) Which is safest?

In my opinion, the answer in both cases is the old ARM rule: no deletion
through a const pointer.

  Dave Harris, Nottingham, UK | "Weave a circle round him thrice,
      brangdon@cix.co.uk      |   And close your eyes with holy dread,
                              |  For he on honey dew hath fed
 http://www.bhresearch.co.uk/ |   And drunk the milk of Paradise."


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: zivca@netvision.net.il (Ziv Caspi)
Date: 1999/09/13
Raw View
On 12 Sep 1999 00:07:51 GMT, ncm@nospam.cantrip.org (Nathan Myers)
wrote:

>
>Lisa Lippincott  <lisa_lippincott@advisories.com> wrote:
>>Most people will also agree that the demolition of an object should
>>reverse the creation.  Thus:
>>
>>   First, the lifetime of the object ends;
>>   second, the body of the destructor is executed;
>>   third, subobjects are destroyed;
>>   finally, storage is released.
>>
>>Looking at this chronology, it's clear that the destructor does not
>>operate on the object -- instead, it operates on the subobjects.  The
>>question of whether the former object was const is moot.
>>
>>So there is no sense in which destruction or deletion is a non-const
>>operation.

[...]
>Still, if you insist on the theoretical approach, then we can say that,
>yes, once the destructor is entered the question of const or non-const
>is moot.  However, the question was of who should be allowed to cause
>the destructor to be entered.  Thus, Lippincott's argument purely begs
>the question.

It also answers it. By symmetry, whoever gets to call the constructor
for const objects also gets the right to call its destructor.

The usual argument against it is that when the destructor is called,
the object is still const. This argument ignores the inherent symmetry
between constructor and destructor.

`What', you say? `They is no such symmetry!'. Of course there is.
Otherwise, making a destructor private would not have sufficed to
deny clients the right to create auto objects of the class:

  class T {
    ~T();
  };


  void f() {
  T t; // Destructor inaccessible. Illegal.
  }

The fact that this is illegal shows the symmetry.

>What is it about this issue that leads people to advance arguments so
>clearly stated, but logically bankrupt?

As long as people on this list (some, unlike me, with lots of
credentials behind them) continue to invest in this particular
venture, I would not consider their position `bankrupt'.

---------------------------------------------
Ziv Caspi
zivca@netvision.net.il
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: niklasb@my-deja.com
Date: 1999/09/14
Raw View
In article <37dad1df$0$225@nntp1.ba.best.com>,
  ncm@nospam.cantrip.org (Nathan Myers) wrote:
>
> Lisa Lippincott  <lisa_lippincott@advisories.com> wrote:
> >Most people will also agree that the demolition of an object should
> >reverse the creation.  Thus:
> >
> >   First, the lifetime of the object ends;
> >   second, the body of the destructor is executed;
> >   third, subobjects are destroyed;
> >   finally, storage is released.
> >
> >Looking at this chronology, it's clear that the destructor does not
> >operate on the object -- instead, it operates on the subobjects.  The
> >question of whether the former object was const is moot.
> >
> >So there is no sense in which destruction or deletion is a non-const
> >operation.
>
> This assertion has been made repeatedly by apologists for the (now)
> status quo.  As in the case of most purely theoretical arguments, it
> completely ignores the consequences of the alternatives.  It is in
the
> consequences where we find the differences that affect programming.
>
> Still, if you insist on the theoretical approach, then we can say
that,
> yes, once the destructor is entered the question of const or non-
const
> is moot.  However, the question was of who should be allowed to cause
> the destructor to be entered.  Thus, Lippincott's argument purely
begs
> the question.

Theoretical arguments have been advanced on both sides. It has
been argued several times that deleting a pointer-to-const is
a const violation because a delete expression calls a non-const
method: the destructor. Lisa's argument demonstrates the flaw
in this reasoning. A delete expression first ends the lifetime
of an object and _then_ calls the destructor, at which time
constness is not an issue.

The question remains whether "ending the existence of" an object
constitutes "changing" that object. Some would say yes, and view
it as so obvious that no further analysis is possible. But if you
change a thing, you should be able to inspect it before and after
and find some difference; you cannot inspect an object that has
been deleted. You might say you changed the object's 'existence',
but this is not an attribute of the object. If an object had an
'existence' attribute it would always be true, for you cannot
refer at all to a non-existent object. Whether a particular object
exists or not is not part of the state of that object, but a fact
about the state of the program as a whole.

My point is not to argue either side on the basis of theory, but
to show that pure logic does not dictate, one way or the other,
whether const should apply to deletion.

> The decision to break const for the case of delete-expressions may
turn
> out to be a minor wart in the language.  What is far worse, in my
view,
> is the breakdown in logical reasoning processes it seems to bring
> repeatedly to the surface.  Lippincott's attempt at argument by
begging
> the question was far from the first, and probably will not be the
last,
> that we have seen here.
>
> What is it about this issue that leads people to advance arguments so
> clearly stated, but logically bankrupt?

Now who's begging the question? Neither the narrow definition of
const in the current language, nor the broader definition you
prefer is inherently more "correct" or valid than the other. Your
reference to the "decision to break const" distorts the issue by
framing it as a choice between a "broken" design and a valid one.

The best design would be the one that struck the best balance
between convenience and safety. I tend to think the committee made
the right choice, mainly because preventing deletion of pointer-
to-const would not buy much safety. For example:

  void Func()
  {
    T info;
    GetInfo(&info); // changes info
  }

Even if const applied to deletion, we still could not prevent
GetInfo from "accidentally" deleting its argument. It would be
more useful if we could simultaneously grant change access and
deny delete access. This reinforces my view that state (which
is the domain of const) is separate from existence/duration
(which is not expressed in the type system).


Sent via Deja.com http://www.deja.com/
Share what you know. Learn what you don't.
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/14
Raw View
Ziv Caspi <zivca@netvision.net.il> wrote:
>ncm@nospam.cantrip.org (Nathan Myers) wrote:
>>Lisa Lippincott  <lisa_lippincott@advisories.com> wrote:
>>>...  it's clear that the destructor does not
>>>operate on the object -- instead, it operates on the subobjects.  The
>>>question of whether the former object was const is moot.
>>>
>>>So there is no sense in which destruction or deletion is a non-const
>>>operation.
>
>>
>> ... once the destructor is entered the question of const or non-const
>>is moot.  However, the question was of who should be allowed to cause
>>the destructor to be entered.  Thus, Lippincott's argument purely begs
>>the question.
>
>It also answers it. By symmetry, whoever gets to call the constructor
>for const objects also gets the right to call its destructor.

To beg the question is to _fail_ to answer it.  You may assume the
conclusion only if use it to show a contradiction in arguments for it.
You cannot support a conclusion by assuming it.  This is elementary.

>The usual argument against it is that when the destructor is called,
>the object is still const. This argument ignores the inherent symmetry
>between constructor and destructor.

Again, purely theoretical arguments, e.g. about "symmetry", fail
to consider engineering consequences.  You can make up arguments
to support anything at all if you carefully avoid discussing
consequences.

>>What is it about this issue that leads people to advance arguments so
>>clearly stated, but logically bankrupt?
>
>As long as people on this list (some, unlike me, with lots of
>credentials behind them) continue to invest in this particular
>venture, I would not consider their position `bankrupt'.

The expression "good money after bad" comes to mind.  Those who
argued in committee for breaking const have an emotional investment
in the breakage.  Advancing logically-unsound arguments in its
favor, and failing to respond to demonstrations that it was a
serious mistake, are the nature of the continued investment.

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/14
Raw View
In article <7rjh8g$2mv$1@nnrp1.deja.com>, niklasb@my-deja.com writes
>But if you
>change a thing, you should be able to inspect it before and after
>and find some difference; you cannot inspect an object that has
>been deleted. You might say you changed the object's 'existence',
>but this is not an attribute of the object. If an object had an
>'existence' attribute it would always be true, for you cannot
>refer at all to a non-existent object. Whether a particular object
>exists or not is not part of the state of that object, but a fact
>about the state of the program as a whole.

In a reference counted object it is perfectly reasonable to require that
the object data is not changed while allowing its reference count
(presumably mutable) to be lowered by one.  In such cases it is possible
to delete an object and examine the data afterwards.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: ncm@nospam.cantrip.org (Nathan Myers)
Date: 1999/09/12
Raw View
Lisa Lippincott  <lisa_lippincott@advisories.com> wrote:
>Most people will also agree that the demolition of an object should
>reverse the creation.  Thus:
>
>   First, the lifetime of the object ends;
>   second, the body of the destructor is executed;
>   third, subobjects are destroyed;
>   finally, storage is released.
>
>Looking at this chronology, it's clear that the destructor does not
>operate on the object -- instead, it operates on the subobjects.  The
>question of whether the former object was const is moot.
>
>So there is no sense in which destruction or deletion is a non-const
>operation.

This assertion has been made repeatedly by apologists for the (now)
status quo.  As in the case of most purely theoretical arguments, it
completely ignores the consequences of the alternatives.  It is in the
consequences where we find the differences that affect programming.

Still, if you insist on the theoretical approach, then we can say that,
yes, once the destructor is entered the question of const or non-const
is moot.  However, the question was of who should be allowed to cause
the destructor to be entered.  Thus, Lippincott's argument purely begs
the question.

The decision to break const for the case of delete-expressions may turn
out to be a minor wart in the language.  What is far worse, in my view,
is the breakdown in logical reasoning processes it seems to bring
repeatedly to the surface.  Lippincott's attempt at argument by begging
the question was far from the first, and probably will not be the last,
that we have seen here.

What is it about this issue that leads people to advance arguments so
clearly stated, but logically bankrupt?

--
Nathan Myers
ncm@nospam.cantrip.org  http://www.cantrip.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://reality.sgi.com/austern_mti/std-c++/faq.html              ]






Author: Francis Glassborow <francis@robinton.demon.co.uk>
Date: 1999/09/10
Raw View
In article <user-0909990948530001@aus-as3-037.io.com>, blargg <postmast.
root.admi.gov@iname.com> writes
>It seems that there is a lot of emotion involved in this issue, and many
>"blown fuses", so I'm not really expecting that any reasonable discussion
>will take place here on the matter.
>
>As usual, everything is connected, and this issue flows into lots of other
>issues in the language. I'd like to understand better the tradeoffs (and
>mistakes) made, so that when I am desinging language-level mechanisms for
>programs to use, I can incorporate experience of others into them.

Exploring this issue as instructive in language design is fine.  However
remember that a degree of pragmatism was involved in the design of C++
(actually that is something that helped make it a popular language).
OTOH there is no way that the rule will change in so far as C++ is
concerned.  Not now nor, IMO, ever.  There is just too much code already
written to the present rules.


Francis Glassborow      Journal Editor, Association of C & C++ Users
64 Southfield Rd
Oxford OX4 1PA          +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: Lisa Lippincott <lisa_lippincott@advisories.com>
Date: 1999/09/10
Raw View
Andrew Koenig <ark@research.att.com> opined:
> The argument that I consider the strongest, and to which I have
> never seen a counterargument that is the least bit convincing,
> is that if you are allowed to create an object, you should be
> allowed to destroy it.

While I think that argument carries considerable practical force, this
abstract argument may be more convincing to some:

Consider the sequence of steps involved in creating an object.

   First, storage is obtained;
   second, subobjects are constructed;
   third, the body of the constructor is executed;
   finally, the lifetime of the object begins.  If the object is const,
      it may not be modified.

It's pretty hard to argue for a different arrangement.  Does anyone want
to try?

Most people will also agree that the demolition of an object should
reverse the creation.  Thus:

   First, the lifetime of the object ends;
   second, the body of the destructor is executed;
   third, subobjects are destroyed;
   finally, storage is released.

Looking at this chronology, it's clear that the destructor does not
operate on the object -- instead, it operates on the subobjects.  The
question of whether the former object was const is moot.

So there is no sense in which destruction or deletion is a non-const
operation.

                                                   --Lisa Lippincott
---
[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]





Author: postmast.root.admi.gov@iname.com (blargg)
Date: 1999/09/09
Raw View
In article <FHr74p.EMw@research.att.com>, ark@research.att.com (Andrew
Koenig) wrote:

> In article <7r2m1t$n61$1@shell7.ba.best.com>,
> Nathan Myers <ncm@nospam.cantrip.org> wrote:
>
> >Still, none of the committee members
> >who argued for breaking const has conceded the point in public, despite
> >demolition of all their arguments; each has just dropped the subject.
>
> This statement is not true.  I continue to believe that the
> decision to allow const objects to be deleted was the correct
> one, and I do not consider my arguments to have been demolished.

(this was the can of worms I was hinting at, Siemel, and why I suggested
that Nathan could perhaps e-mail me in private :-)

> The argument that I consider the strongest, and to which I have
> never seen a counterargument that is the least bit convincing,
> is that if you are allowed to create an object, you should be
> allowed to destroy it.
>
> That is, in
>
>         template<class T> void f(args) {
>
>                 // ...
>
>         }
>
> I should be able to say
>
>         T* tp = new T;
>         delete tp;
>
> There are other arguments, which other people may find more convincing,
> but I personally think that this one is the strongest.

    template<typename T>
    struct remove_const {
        typedef T type;
    };

    template<typename T>
    struct remove_const<T const> {
        typedef T type;
    };

    typedef typename remove_const<T>::type T_non_const;

    T* tp = new T_non_const;
    delete const_cast<T_non_const*> (tp);

(or, as Nathan suggested, a deletion function that takes a const pointer
and casts it to non-const)

This one certainly shows an inconsistency in the concept, for sure.
Inconsistencies can pollute a simple concept, making it harder to
understand and apply consistently.

I'm not sure what the practical effect of the above is, though. Why would
T be a const type, and some function allocating and deallocating objects
of that type? What would it do with the objects once they were created? I
think this problem is more an issue that T could be a const type, and
interaction with templates. This points to a much bigger picture of
inconsistency. Making const consistent with this bigger inconsistency
isn't necessarily useful.

I've certainly run into many inconsistencies with templates (and even
simple typedefs) not related to deleting const objects.

> I understand that my point of view is not universally held, and
> I have no problem if other people hold other opinions.  However,
> this argument has not been demolished, and if I have appeared to
> drop the subject, it is only because there is a limit to how many
> times I am willing to repeat myself in the absence of new evidence.

With the help of Nathan, I have called into question the meaning and use
of const.

I question whether it's a theoretically-pure concept or one of more
practical value. I am now leaning more towards the practical side. Bjarne
mentions that the concept came about from his experience with hardware
write-protection in operating systems (D&E page 90). There he describes
the concept evolving to suit practical needs (using it as a type
modifier).

As Nathan said, I think const was meant to provide a way to allow
something to access an object *without* messing with it. The class of the
object should decide exactly what "messes" with it. Member functions can
be declared "const" to allow this. The class should also be able to say
whether destruction is considered a modification or not. In the absence of
such a mecanism, it seems that prevent deletion of const is safer.

I suppose one could create two classes, and do away with const altogether:

    class Foo_const {
    protected:
        void non_const();
        ~Foo_const();
    public:
        void const_f();
    };

    class Foo : public Foo_const {
    public:
        using Foo_const::non_const;
        ~Foo() { }
    };

    void f( Foo_const* foo ) {
        foo->const_f();   // OK
        foo->non_const(); // illegal
        delete foo;       // illegal
    }

    void g( Foo* foo ) {
        foo->const_f();   // OK
        foo->non_const(); // OK
        delete foo;       // OK
    }

It seems that there is a lot of emotion involved in this issue, and many
"blown fuses", so I'm not really expecting that any reasonable discussion
will take place here on the matter.

As usual, everything is connected, and this issue flows into lots of other
issues in the language. I'd like to understand better the tradeoffs (and
mistakes) made, so that when I am desinging language-level mechanisms for
programs to use, I can incorporate experience of others into them.


[ 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://reality.sgi.com/austern_mti/std-c++/faq.html              ]