Topic: Why can't static member functions be const?
Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Thu, 11 Aug 1994 11:31:09 GMT Raw View
In article <rfgCu5oyA.6KH@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:
>
>P.P.S. The *real* problem is that it is nowhere defined what it means
>for something to be ``a part of'' something else. Is a static data member
>of a type T ``a part of'' each object of type T? Well, yes and no. It
>is *logically* a part of each such object, but *physically* it may not
>be.
But now the committee _is_ working hard to say what
an object actually is. My guess is that static data members
of a class are not subobjects of an object of the class type.
So the restriction does not apply to them.
--
JOHN (MAX) SKALLER, INTERNET:maxtal@suphys.physics.su.oz.au
Maxtal Pty Ltd,
81A Glebe Point Rd, GLEBE Mem: SA IT/9/22,SC22/WG21
NSW 2037, AUSTRALIA Phone: 61-2-566-2189
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 7 Aug 1994 08:30:09 GMT Raw View
In article <Ctp1rJ.Myp@cwi.nl> olaf@cwi.nl (Olaf Weber) writes:
>A const member function may indeed change static members...
I think you are assuming things which the current draft C++ standard isn't
at all clear about.
In the latest draft, section 9.4.1 contains the following:
struct s {
int a;
int f() const;
int g() { return a++; }
int h() const { return a++; } // error
};
int s::f() const { return a; }
"The a++ in the body of s::h is ill-formed because it tries to
modify (a part of) the object for which s::h() is called. This
is not allowed in a const member function..."
So the rule is that you cannot modify the values of data members within
a `const' member function.
If you believe that there is a special exception in the case of static
data members, please cite chapter and verse from the latest draft to
support that contention.
P.S. I happen to agree that there *should* be a special exception in the
case of static data members. It's just that the draft standard doesn't
seem to support that view at the moment.
P.P.S. The *real* problem is that it is nowhere defined what it means
for something to be ``a part of'' something else. Is a static data member
of a type T ``a part of'' each object of type T? Well, yes and no. It
is *logically* a part of each such object, but *physically* it may not
be.
--
-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -
Author: jason@cygnus.com (Jason Merrill)
Date: Sun, 7 Aug 1994 10:15:32 GMT Raw View
>>>>> Ronald F Guilmette <rfg@netcom.com> writes:
> "The a++ in the body of s::h is ill-formed because it tries to
> modify (a part of) the object for which s::h() is called. This
> is not allowed in a const member function..."
> So the rule is that you cannot modify the values of data members within
> a `const' member function.
> If you believe that there is a special exception in the case of static
> data members, please cite chapter and verse from the latest draft to
> support that contention.
I would argue that this paragraph is merely an elaboration of the general
principle stated in 7.1.5.1:
each |
non-function, non-static, non-mutable member of a const class object
is const (9.4.1).
Jason
Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sun, 7 Aug 1994 20:31:56 GMT Raw View
In article <JASON.94Aug7031532@deneb.cygnus.com> jason@cygnus.com (Jason Merrill) writes:
>>>>>> Ronald F Guilmette <rfg@netcom.com> writes:
>
>> "The a++ in the body of s::h is ill-formed because it tries to
>> modify (a part of) the object for which s::h() is called. This
>> is not allowed in a const member function..."
>
>> So the rule is that you cannot modify the values of data members within
>> a `const' member function.
>
>> If you believe that there is a special exception in the case of static
>> data members, please cite chapter and verse from the latest draft to
>> support that contention.
>
>I would argue that this paragraph is merely an elaboration of the general
>principle stated in 7.1.5.1:
>
> each |
> non-function, non-static, non-mutable member of a const class object
> is const (9.4.1).
That rule clearly indicates that things belonging to a certain set (which,
for brevity, we might call `X') have the `const' property. It *does not*
unambiguously indicate that things which are NOT in the set X always (and
necessarily) DO NOT have the have the `const' property. It may seem to
vaguely imply it, but it sure as heck doesn't say it. And even if it
*did* say it, that would quite cleary be wrong, as the following example
illustrates:
struct S { static int const mbr; } const obj;
int const S::mbr = 99;
Here we have something which is clearly NOT in the set X (i.e. a member
which is static rather than non-static) and which nontheless has the
`const' property.
--
-- Ron Guilmette, Sunnyvale, CA ---------- RG Consulting -------------------
---- domain addr: rfg@netcom.com ----------- Purveyors of Compiler Test ----
---- uucp addr: ...!uunet!netcom!rfg ------- Suites and Bullet-Proof Shoes -
Author: jason@cygnus.com (Jason Merrill)
Date: Sun, 7 Aug 1994 22:12:33 GMT Raw View
>>>>> Ronald F Guilmette <rfg@netcom.com> writes:
> That rule clearly indicates that things belonging to a certain set (which,
> for brevity, we might call `X') have the `const' property. It *does not*
> unambiguously indicate that things which are NOT in the set X always (and
> necessarily) DO NOT have the have the `const' property. It may seem to
> vaguely imply it, but it sure as heck doesn't say it. And even if it
> *did* say it, that would quite cleary be wrong, as the following example
> illustrates:
> struct S { static int const mbr; } const obj;
> int const S::mbr = 99;
> Here we have something which is clearly NOT in the set X (i.e. a member
> which is static rather than non-static) and which nontheless has the
> `const' property.
My quote was an incomplete summary of set X; 7.1.5.1 also states that
elements of a const array are const, and that declarations that specify
const indicate a const object. That last one covers your example.
Are you now going to suggest that because 7.1.5.1 does not explicitly state
that
int foo;
is not const, that an implementation is free to make it const? I will
agree that perhaps stricter wording is called for, but I will not agree
that the intent is at all vague.
Jason
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Mon, 8 Aug 1994 15:44:16 GMT Raw View
rfg@netcom.com (Ronald F. Guilmette) writes:
>In article <Ctp1rJ.Myp@cwi.nl> olaf@cwi.nl (Olaf Weber) writes:
>>A const member function may indeed change static members...
>
>I think you are assuming things which the current draft C++ standard isn't
>at all clear about.
[...]
>If you believe that there is a special exception in the case of static
>data members, please cite chapter and verse from the latest draft to
>support that contention.
7.1.5.1, paragraph 2:
Each element of a const array is const and each non-function,
non-static, non-mutable member of a const class object is const
(9.4.1).
>So the rule is that you cannot modify the values of data members within
>a `const' member function.
No, the rules are that you cannot modify const objects, and that
`*this' is a const object within a const member function, and that
non-static, non-function, non-mutable members of const objects
are const. Together these imply that you cannot modify the values of
non-static, non-mutable data members (but that is a conclusion deduced
from the rules, not a rule itself).
--
Fergus Henderson - fjh@munta.cs.mu.oz.au
Author: fjh@munta.cs.mu.OZ.AU (Fergus Henderson)
Date: Mon, 1 Aug 1994 01:18:24 GMT Raw View
baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes:
>I think some clarification is needed over the efect of const on a member
>function (static or not) on how it can access static member data. I would
>have thought that a const member function would not be able any member
>data of the class, I think I infer from your description that it can
>modify static data.
Static members of const objects are not necessarily const.
ARM 7.1.6: "Each nonfunction, NONSTATIC member of a `const' class object
is `const'" (my emphasis).
>I understand Jason's view as:
>
> | member data
>member function | not static | static
>---------------------------------------------------
>not const, not static | READ/WRITE | READ/WRITE
>const , not static | READ | READ/WRITE *
>not const, static |NOT APPLICABLE| READ/WRITE
>const , static |NOT APPLICABLE| READ/WRITE *
>
> * is where the difference is
Jason's view is correct.
--
Fergus Henderson - fjh@munta.cs.mu.oz.au
Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 28 Jul 1994 21:10:06 GMT Raw View
>>>>> David Lohmann <dlohmann@uhunix.uhcc.Hawaii.Edu> writes:
>> int Inc2() { return b++;}
>> int ConstMethod1() const { return Inc2(); }
>> "main2.cc", line 16: warning: non-const member function A::Inc2() called for const object (anachronism)
> ^^^^^ when you specify const this way,
> you are telling compiler that you don't want to change internal
> state of object. If you call Inc2, you _WILL_ change the
> state of object by incrementing member, albeit a static member.
That is irrelevant. The compiler doesn't care about the contents of Inc2()
at the point where it issues the warning; all it cares about is that Inc2()
is non-const and ConstMethod1() IS const. Calling the one from the other
is illegal for that reason and that reason alone. If Inc2() were { }
the call would still be illegal.
Jason
Author: olaf@cwi.nl (Olaf Weber)
Date: Fri, 29 Jul 1994 08:47:31 GMT Raw View
In article <31924f$9se@hpsystem1.informatik.tu-muenchen.de>, schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann) writes:
> class A {
> public:
> static int si;
> int i;
> void f() const;
> };
> void incr_A_si ()
> {
> A::si++; // ok
> }
> void A::f () const
> {
> i++; // error
> si++; // error ???
> incr_A_si(); // ok !
> }
> Can it be that a const memberfunction (static or not)
> may not change the static data of its class?
A const member function may indeed change static members. A compiler
that gives an error at the "???" line is broken.
> If so, const MEMBER-functions would have more restrictions
> modifiying the static data of THEIR class than ANY OTHER
> function.
This would be an absurd situation, and it is the rationale behind
allowing const member functions to change non-const static members.
> I just can't believe that such a limitation has any use.
> If it were so, than we would need static mutable data
> of a class, so that const memberfunctions may change it.
Which would further clutter up the language for absolutely no gain
whatsoever.
-- Olaf Weber
Author: schuenem@Informatik.TU-Muenchen.DE (Ulf Schuenemann)
Date: 28 Jul 1994 19:49:35 GMT Raw View
class A {
public:
static int si;
int i;
void f() const;
};
void incr_A_si ()
{
A::si++; // ok
}
void A::f () const
{
i++; // error
si++; // error ???
incr_A_si(); // ok !
}
Can it be that a const memberfunction (static or not)
may not change the static data of its class?
If so, const MEMBER-functions would have more restrictions
modifiying the static data of THEIR class than ANY OTHER
function.
I just can't believe that such a limitation has any use.
If it were so, than we would need static mutable data
of a class, so that const memberfunctions may change it.
Ulf Schuenemann
--------------------------------------------------------------------
Ulf Sch nemann
Institut f r Informatik, Technische Universit t M nchen.
email: schuenem@informatik.tu-muenchen.de
Author: jason@cygnus.com (Jason Merrill)
Date: Thu, 28 Jul 1994 21:18:18 GMT Raw View
>>>>> Olaf Weber <olaf@cwi.nl> writes:
> What you proposed would amount to a declaration that a function doesn't
> have any side-effects, which cannot be expressed in C++.
Though many compilers have extensions to that effect. g++ allows you to
write '__attribute__ ((const))' after the function declaration. Other
compilers have things like '#pragma no_side_effects'.
Jason
Author: dlohmann@uhunix.uhcc.Hawaii.Edu (David Lohmann)
Date: Thu, 28 Jul 1994 07:14:58 GMT Raw View
In article <1994Jul25.133043.3479@ericsson.se> etxmlkn@aom.ericsson.se writes:
>I've search through the ARM without finding any answer to this question, so I wonder if someone could enlighten me.
>
>Consider following (stupid) example:
>class A
>{
> static int b;
>public:
> A() {}
> static const char* A::Get() { return "A";}
> static int Inc0() { return b++;}
> static int Inc1() const { return b++;}
> int Inc2() { return b++;}
>
> const char * ConstMethod0() const { return A::Get(); }
> int ConstMethod1() const { return Inc2(); }
^^^^^ when you specify const this way,
you are telling compiler that you don't want to change internal
state of object. If you call Inc2, you _WILL_ change the
state of object by incrementing member, albeit a static member.
If you are asking:
"Since b is static, then why does compiler flag
non-static member fn, since no non-static members are changed?"
then I guess you can see ARM 9.3.1. The warning
is a anachronism because, as the ARM states:
"In early implementations of C++, *this* was
non-*const*...".
Although static members are not addressed with *this*,
this may be reason for warning.
> int ConstMethod2() const { return A::Inc(); }
>};
>
>CC main2.cc
>"main2.cc", line 16: warning: non-const member function A::Inc2() called for const object (anachronism)
>
>1 - why
>
>/Mikael
Peter
--
//-----------------------------------------------------------
// D. Peter Lohmann
//-----------------------------------------------------------
Author: olaf@cwi.nl (Olaf Weber)
Date: Thu, 28 Jul 1994 13:52:48 GMT Raw View
In article <CtnFJG.IKs@ukpsshp1.serigate.philips.nl>, baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes) writes:
> I think some clarification is needed over the efect of const on a member
> function (static or not) on how it can access static member data. I would
> have thought that a const member function would not be able any member
> data of the class, I think I infer from your description that it can
> modify static data.
For example:
class A {
static int si;
mutable int mi;
int i;
public:
void f() const;
void g();
};
The `const' affects the type of `this' in a member function. Inside
`A::g()', the type of `this' is `A * const', while inside `A::f()' the
type of `this' is `A const * const'.
This means that any members of the _object_ pointed at by `this' in
`A::f()' cannot be changed, unless they are declared "mutable" like
`A::mi'.
"A static member is not part of objects of a class." (ARM 9.4)
Therefore the "constness" of the objects for which a member function
is called does not affect them.
Thus `A::f()' can change `A::si' and `A::mi', but not `A::i', while
`A::g()' can change them all.
Another consequence is that you cannot declare "const static member
functions", as they don't have a this pointer. What you proposed
would amount to a declaration that a function doesn't have any
side-effects, which cannot be expressed in C++.
-- Olaf Weber
Author: baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes)
Date: Thu, 28 Jul 1994 11:50:03 GMT Raw View
Jason Merrill (jason@cygnus.com) wrote:
: >>>>> Stephen Baynes <baynes@ukpsshp1.serigate.philips.nl> writes:
: > But the static member function can access the static data members - so a
: > const static member function could not modify these and a non const
: > static memeber funtion could.
: But this distinction is not useful. For non-static member functions,
: designating them 'const' or 'volatile' (or not) affects the type of 'this',
: and which objects they can be called for. Static member functions are
: called without an associated object, so there's no notion of 'const object'
: to check the call against. You can't refer to a 'const translation unit'
: or anything like that.
I think some clarification is needed over the efect of const on a member
function (static or not) on how it can access static member data. I would
have thought that a const member function would not be able any member
data of the class, I think I infer from your description that it can
modify static data.
My belief can be summarised in this table:
| member data
member function | not static | static
---------------------------------------------------
not const, not static | READ/WRITE | READ/WRITE
const , not static | READ | READ
not const, static |NOT APPLICABLE| READ/WRITE
const , static |NOT APPLICABLE| READ
I understand Jason's view as:
| member data
member function | not static | static
---------------------------------------------------
not const, not static | READ/WRITE | READ/WRITE
const , not static | READ | READ/WRITE *
not const, static |NOT APPLICABLE| READ/WRITE
const , static |NOT APPLICABLE| READ/WRITE *
* is where the difference is
Will someone clarify please.
--
Stephen Baynes baynes@mulsoc2.serigate.philips.nl
Philips Semicondutors Ltd
Southampton My views are my own.
United Kingdom
Author: mkohtala@lk-hp-19.hut.fi (Marko Kohtala)
Date: 25 Jul 94 21:20:18 GMT Raw View
etxmlkn@aom.ericsson.se (Mikael Karlsson) writes:
>I've search through the ARM without finding any answer to this question, so I wonder if someone could enlighten me.
>Consider following (stupid) example:
>class A
>{
> static int b;
>public:
> A() {}
> static const char* A::Get() { return "A";}
> static int Inc0() { return b++;}
> static int Inc1() const { return b++;}
> int Inc2() { return b++;}
> const char * ConstMethod0() const { return A::Get(); }
> int ConstMethod1() const { return Inc2(); }
> int ConstMethod2() const { return A::Inc(); }
>};
>CC main2.cc
>"main2.cc", line 16: warning: non-const member function A::Inc2() called for const object (anachronism)
>1 - why
Actually, you should get an error on the line where you define the
static const member function. There is no point in having a static
const member function, since const member function deals with const
object only and static member does not deal with any object. If there
is no object, there is no point in it being const.
You can call a static member function like this:
A a;
a.Inc0();
but the effect is just the same if you wrote it like this:
A::Inc0();
--
---
Marko.Kohtala@hut.fi, Marko.Kohtala@compart.fi, Marko.Kohtala@ntc.nokia.com
Student at (not representative of) the Helsinki University of Technology
(This is an information virus: if you know of it, you are infected.)
Author: baynes@ukpsshp1.serigate.philips.nl (Stephen Baynes)
Date: Tue, 26 Jul 1994 11:16:08 GMT Raw View
Marko Kohtala (mkohtala@lk-hp-19.hut.fi) wrote:
: etxmlkn@aom.ericsson.se (Mikael Karlsson) writes:
: Actually, you should get an error on the line where you define the
: static const member function. There is no point in having a static
: const member function, since const member function deals with const
: object only and static member does not deal with any object. If there
: is no object, there is no point in it being const.
But the static member function can access the static data members - so
a const static member function could not modify these
and a non const static memeber funtion could.
--
Stephen Baynes baynes@mulsoc2.serigate.philips.nl
Philips Semicondutors Ltd
Southampton My views are my own.
United Kingdom
Author: jason@cygnus.com (Jason Merrill)
Date: Wed, 27 Jul 1994 05:49:10 GMT Raw View
>>>>> Stephen Baynes <baynes@ukpsshp1.serigate.philips.nl> writes:
> But the static member function can access the static data members - so a
> const static member function could not modify these and a non const
> static memeber funtion could.
But this distinction is not useful. For non-static member functions,
designating them 'const' or 'volatile' (or not) affects the type of 'this',
and which objects they can be called for. Static member functions are
called without an associated object, so there's no notion of 'const object'
to check the call against. You can't refer to a 'const translation unit'
or anything like that.
Jason
Author: etxmlkn@aom.ericsson.se (Mikael Karlsson)
Date: Mon, 25 Jul 1994 13:30:43 GMT Raw View
I've search through the ARM without finding any answer to this question, so I wonder if someone could enlighten me.
Consider following (stupid) example:
class A
{
static int b;
public:
A() {}
static const char* A::Get() { return "A";}
static int Inc0() { return b++;}
static int Inc1() const { return b++;}
int Inc2() { return b++;}
const char * ConstMethod0() const { return A::Get(); }
int ConstMethod1() const { return Inc2(); }
int ConstMethod2() const { return A::Inc(); }
};
CC main2.cc
"main2.cc", line 16: warning: non-const member function A::Inc2() called for const object (anachronism)
1 - why
/Mikael
Author: davep@pcproj.datastream.co.uk (Dave Postill)
Date: 25 Jul 1994 16:05:12 +0100 Raw View
Mikael Karlsson (etxmlkn@aom.ericsson.se) wrote:
:>I've search through the ARM without finding any answer to this question, so I wonder if someone could enlighten me.
:>Consider following (stupid) example:
:>class A
:>{
:> static int b;
:>public:
:> A() {}
:> static const char* A::Get() { return "A";}
:> static int Inc0() { return b++;}
:> static int Inc1() const { return b++;}
:> int Inc2() { return b++;}
:> const char * ConstMethod0() const { return A::Get(); }
:> int ConstMethod1() const { return Inc2(); }
:> int ConstMethod2() const { return A::Inc(); }
:>};
:>CC main2.cc
:>"main2.cc", line 16: warning: non-const member function A::Inc2() called for const object (anachronism)
:>1 - why
:>/Mikael
Think about it.
ConstMethod1() returns Inc2().
ConstMethod1() is const().
Inc2() is not const and modifies data.
A const method cannot alter data.
Now do you see it?
=============================================================================
-- Dave Postill Datastream International Ltd
-- Technical Consultant Monmouth House
-- PC Projects 58-64 City Road
-- London EC1Y 2AL
-- Voice: +44 (0)71 250 3000 Ext 1602 England
-- Fax: +44 (0)71 336 1952
-- Email: davep@pcproj.datastream.co.uk
=============================================================================