Topic: Constness by default


Author: fjh@murlibobo.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/25
Raw View
Oleg Zabluda <zabluda@math.psu.edu> writes:

>Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
>: Michael Podolsky <michaelp@scanvec.com> writes:
>
>: >Seems like constness would better be the default for variable
>: >and class method declarations. And non-constness should be
>: >expressed explicitly.
>
>: I agree.  Unfortunately backwards compatibility considerations
>: make this basically impossible for C++... but this is a good
>: idea for future language designs.
[...]
>I disagree. I remember we had a huge fight in clc++m about half a year ago
>about the meaning of const member functions. I claimed that declaring
>a method const means that you allow to apply it to const objects,
>not that you guarantee that the method would not mutate the object or
>"somehow allow one to mutate the object". I even half-jokingly proposed
>a new keyword "const_method" to allow expressing the later. Whether we like
>it or not, the current C++ rules mean the former,

Well, I missed the bunfight in clc++m...  but IMHO `const' does mean
that you won't mutate the logical state of the object.  You're right
that the C++ rules don't guarantee this, but that's what it means.
Don't forget that programming languages are for communication, not just
for execution.  The compiler may not prevent you from lying, but if
you declare a method `const' and then the method does change the
logical state of the object, then you have lied.

>thus non-const default is exactly the right thing.

Even if we were to accept your argument about the meaning of `const'
(which I don't), I don't see how this would follow.  I think it would
still be better for `const' to be the default.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1997/11/26
Raw View
Fergus Henderson <fjh@murlibobo.cs.mu.OZ.AU> wrote:
: Oleg Zabluda <zabluda@math.psu.edu> writes:

: >Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
: >: Michael Podolsky <michaelp@scanvec.com> writes:
: >
: >: >Seems like constness would better be the default for variable
: >: >and class method declarations. And non-constness should be
: >: >expressed explicitly.
: >
: >: I agree.  Unfortunately backwards compatibility considerations
: >: make this basically impossible for C++... but this is a good
: >: idea for future language designs.
: [...]
: >I disagree. I remember we had a huge fight in clc++m about half a year ago
: >about the meaning of const member functions. I claimed that declaring
: >a method const means that you allow to apply it to const objects,
: >not that you guarantee that the method would not mutate the object or
: >"somehow allow one to mutate the object". I even half-jokingly proposed
: >a new keyword "const_method" to allow expressing the later. Whether we like
: >it or not, the current C++ rules mean the former,

: Well, I missed the bunfight in clc++m...  but IMHO `const' does mean
: that you won't mutate the logical state of the object.  You're right
: that the C++ rules don't guarantee this, but that's what it means.

No it doesn't. That's what programmers are usually _trying_ to
communicate to the compiler and other programmers, but it
is not what it means in C++, IMHO.

Let me try summarize my arguments from half a year ago.

class T {
 public:
   T& f() /* non-const */ { return *this; }

   void g() const {};
   void g()       {};
};

Here neither f() nor the second g() can be declared const (although for
different reasons), despite the fact that they neither change nor "somehow
allow to change" a bitwize or logical state of an object, simply because
T doesn't have any. There is nothing there to change.

: Don't forget that programming languages are for communication, not just
: for execution.  The compiler may not prevent you from lying, but if
: you declare a method `const' and then the method does change the
: logical state of the object, then you have lied.

No I didn't. Because the only thing I promised is that "this method
can be [safely] applied to const objects". If we go deeper into
the meaning of "the logical state of the object" we soon realize
that there are as many opinions on what it means as there are programmers.
In fact, often one programmer have several different opinions on
the subject, depending on the time of the day :-). That's why in the
example above I did my best to altogether eiminate considerations
of the meaning of "the logical state of the object". What you describe
is a programming paradigm akin to "no goto's, please", not a language
rule. Language rules simply say that in const method this is a
pointer to const, that's all.

: >thus non-const default is exactly the right thing.

: Even if we were to accept your argument about the meaning of `const'
: (which I don't), I don't see how this would follow.

Because if I am right then adding "const" to a method's cv-qualifier
should be a conscientious desision on a programmer's part because
it means "I allow to apply this method to const objects".

: I think it would
: still be better for `const' to be the default.

Maybe a better idea would be to make all variables to be `const'
by default, unless explicitly declared `mutable'. Nowdays most
of my variables are const anyway.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/26
Raw View
Oleg Zabluda <zabluda@math.psu.edu> writes:
>Fergus Henderson <fjh@cs.mu.OZ.AU> wrote:
>
>: Well, I missed the bunfight in clc++m...  but IMHO `const' does mean
>: that you won't mutate the logical state of the object.  You're right
>: that the C++ rules don't guarantee this, but that's what it means.
>
>No it doesn't. That's what programmers are usually _trying_ to
>communicate to the compiler and other programmers, but it
>is not what it means in C++, IMHO.

Then what does it mean?

The language rules don't give you a definition of its meaning.
They just say what is legal.

The above definition is, as far as I can see, the only reasonable one.
(No, I don't consider "Humpty-Dumpty" definitions reasonable! ;-)

>Let me try summarize my arguments from half a year ago.
>
>class T {
> public:
>   T& f() /* non-const */ { return *this; }
>
>   void g() const {};
>   void g()       {};
>};
>
>Here neither f() nor the second g() can be declared const (although for
>different reasons), despite the fact that they neither change nor "somehow
>allow to change" a bitwize or logical state of an object, simply because
>T doesn't have any. There is nothing there to change.

The fact that there is nothing to change means that the statement that
member Foo won't change the state (or somehow allow it to be changed)
is vacuously TRUE, not false.  Thus, logically speaking, ANY member
function of a class with no state can be declared const.

(As it happens, the language rules mean that if you want to declare f() const,
then you need to also use a const_cast.  This is not a great suprise --
in the general case, logical constness is an undecidable property, so
any given set of rules will have some cases where you may need to use
a const_cast or equivalent.)

>: Don't forget that programming languages are for communication, not just
>: for execution.  The compiler may not prevent you from lying, but if
>: you declare a method `const' and then the method does change the
>: logical state of the object, then you have lied.
>
>No I didn't. Because the only thing I promised is that "this method
>can be [safely] applied to const objects".

But "const" on an object means the object's logical value won't change.
Hence it is not possible to safely apply a member to a const object
if that member changes the object's logical value.
Doing so would be unsafe, in general, because someone may have
assumed that "const" on an object really meant const.

(Here I'm reducing your argument about the definition of "const"
on member functions to an argument about the definition of "const"
on objects.  Maybe you disagree about the latter too.  But I think
that the argument for HumptyDumpty const is harder to defend
if you are talking about const on objects.)

>If we go deeper into
>the meaning of "the logical state of the object" we soon realize
>that there are as many opinions on what it means as there are programmers.

It is up to the designer of each class to decide on what constitutes
the logical state of objects in that class (and to document that
design decision, if it is not clear).

>In fact, often one programmer have several different opinions on
>the subject, depending on the time of the day :-).

In that case, the programmer should choose one design,
document it, and stick to it.

>That's why in the
>example above I did my best to altogether eiminate considerations
>of the meaning of "the logical state of the object". What you describe
>is a programming paradigm akin to "no goto's, please", not a language
>rule.

I know it's not a language rule.  However, that doesn't mean it isn't
important.  It _is_ important, and the language design reflects that
(witness `mutable').

>: >thus non-const default is exactly the right thing.
>
>: Even if we were to accept your argument about the meaning of `const'
>: (which I don't), I don't see how this would follow.
>
>Because if I am right then adding "const" to a method's cv-qualifier
>should be a conscientious desision on a programmer's part because
>it means "I allow to apply this method to const objects".

Ah, I understand you now.

>: I think it would
>: still be better for `const' to be the default.
>
>Maybe a better idea would be to make all variables to be `const'
>by default, unless explicitly declared `mutable'. Nowdays most
>of my variables are const anyway.

Yes, perhaps the default should be for variables to be const,
but member functions non-const.

--
Fergus Henderson <fjh@cs.mu.oz.au>   WWW: <http://www.cs.mu.oz.au/~fjh>
Note: due to some buggy software and a (probably accidental)
denial-of-service attack, any mail sent to me between
 Tue Nov 25 20:00:00 UTC (6am Wed, local time)
and Wed Nov 26 06:00:00 UTC (4pm, local time)
may have gone into the bit-bucket.  Please re-send it.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Oleg Zabluda <zabluda@math.psu.edu>
Date: 1997/11/25
Raw View
Fergus Henderson <fjh@mundook.cs.mu.OZ.AU> wrote:
: Michael Podolsky <michaelp@scanvec.com> writes:

: >Seems like constness would better be the default for variable
: >and class method declarations. And non-constness should be
: >expressed explicitly.

: I agree.  Unfortunately backwards compatibility considerations
: make this basically impossible for C++... but this is a good
: idea for future language designs.

: P.S. My knowledge of Algol is pretty sketchy, but didn't Algol do that?
: Funny how things have progressed over the last 30 years or so.
: I guess it always has to be two steps forward, one step back ;-)

: P.P.S. One thing that compiler vendors could do is to provide optional
: warnings if something that could have been declared const was not.

I disagree. I remember we had a huge fight in clc++m about half a year ago
about the meaning of const member functions. I claimed that declaring
a method const means that you allow to apply it to const objects,
not that you guarantee that the method would not mutate the object or
"somehow allow one to mutate the object". I even half-jokingly proposed
a new keyword "const_method" to allow expressing the later. Whether we like
it or not, the current C++ rules mean the former, thus non-const
default is exactly the right thing. Had the "const" meant the later,
you would have been 100% correct, of course.

Oleg.
--
Life is a sexually transmitted, 100% lethal disease.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: fjh@mundook.cs.mu.OZ.AU (Fergus Henderson)
Date: 1997/11/01
Raw View
Michael Podolsky <michaelp@scanvec.com> writes:

>Seems like constness would better be the default for variable
>and class method declarations. And non-constness should be
>expressed explicitly.

I agree.  Unfortunately backwards compatibility considerations
make this basically impossible for C++... but this is a good
idea for future language designs.

P.S. My knowledge of Algol is pretty sketchy, but didn't Algol do that?
Funny how things have progressed over the last 30 years or so.
I guess it always has to be two steps forward, one step back ;-)

P.P.S. One thing that compiler vendors could do is to provide optional
warnings if something that could have been declared const was not.

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: 1997/11/03
Raw View
Fergus Henderson wrote:
...
> P.P.S. One thing that compiler vendors could do is to provide optional
> warnings if something that could have been declared const was not.

I've used an SGI C compiler that did this. Unfortunately, IMHO, it did
it wrong. For the following code (written purely to illustrate the
issue):

void double2float( double *in, float *out)
{
 int i;
 for(i=0; in[i]!=`\0'; i++)
  out[i] = (float)in[i];
}

It would remind me that 'out' could be declared as 'float *const out',
and that 'in' could be declared as 'double * const in', which are
negligibly useful changes, but wouldn't remind me that 'in' could have
been declared as 'double const * in', which is a very useful change.
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Valentin Bonnard <bonnardv@pratique.fr>
Date: 1997/11/03
Raw View
James Russell Kuyper Jr. wrote:
>
> Fergus Henderson wrote:
> ...
> > P.P.S. One thing that compiler vendors could do is to provide optional
> > warnings if something that could have been declared const was not.
>
> I've used an SGI C compiler that did this. Unfortunately, IMHO, it did
> it wrong.

Even done correctly, it can surprise the beginner and force
him to make error he wouldn't have made:

T& vector<T, Alloc>::operator[] (size_t);

can be declared const ! (logical vs physical constness)

In some cases in would help, but with a clear explannation
in the manual that it the message doesn't means that you
have to make it const. And since beginners don't read
manuals, this should be labelled 'info' or 'message' not
'warning'.

It would help on pointed to types, ex const T* vs T*, not
on const int vs int.

--

Valentin Bonnard                mailto:bonnardv@pratique.fr
info about C++/a propos du C++: http://www.pratique.fr/~bonnardv/
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]