Topic: constness of private members and methods


Author: abell@mindspring.com (Andrew Bell)
Date: 1996/04/22
Raw View
kanze@gabi-soft.fr (J. Kanze) wrote:
>I still think that the pragma idea has merit.  There are functions (like
>exp or sqrt) that you want to the compiler to treat as pure, even though
>they are not pure according to the strict rules.

Hmm.  Considering we have "mutable" for const, perhaps we need
"virginal" for globals that don't affect purity? :-)

Andrew Bell
abell@mindspring.com




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





Author: jbuck@Synopsys.COM (Joe Buck)
Date: 1996/04/06
Raw View
jdmorris@ix.netcom.com (Jason D. Morris) wrote:
>>Assuming you allow 'pure' and 'clean', the compiler would then have
>>to check to make sure your functions were in fact 'pure' and 'clean'.

abell@mindspring.com (Andrew Bell) writes:
>The problem is the compiler needs to know the "purity" of the
>functions a given function calls during its compilation, or it can't
>optimize the code.  You would thus have to compile all the called
>functions first,

No, you wouldn't.  Think of contractual programming, as in Eiffel.
If a keyword associated with a prototype makes a promise (e.g. that
a function has no side effects), users of that function can assume
that promise is kept.  When the compiler compiles the "pure function",
only then does it need to check the function for purity, using only
local information.  No complex analysis is required: any function
calls not so tagged would be assumed to be impure.

>With the proposed idea, a function that claims to pure and isn't would
>be tagged with a compiler error.  This might be problematic with
>templates, as instantiation for a particular type may lead to non-pure
>functions being called.

Replace "pure" with "const".  It's no different.
--
-- Joe Buck  <jbuck@synopsys.com> (not speaking for Synopsys, Inc)

Work for something because it is good,
not just because it stands a chance to succeed.    -- Vaclav Havel
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: abell@mindspring.com (Andrew Bell)
Date: 1996/04/07
Raw View
jbuck@Synopsys.COM (Joe Buck) wrote:
 >abell@mindspring.com (Andrew Bell) writes:
>>The problem is the compiler needs to know the "purity" of the
>>functions a given function calls during its compilation, or it can't
>>optimize the code.  You would thus have to compile all the called
>>functions first,

>No, you wouldn't.

Tsk, tsk, Joe, you misidentified someone else's statements as Jason's,
and then edited out the part I was responding to, thus making it look
like I was responding to something I wasn't.  I was responding to
Jason's comment that "pure" and "clean" as modifiers weren't necessary
with a slightly smarter compiler.  My response was that in that case,
all the code would have to be precompiled for purity/cleanliness,
before anything could be compiled, a statement I still stand by.

>>With the proposed idea, a function that claims to pure and isn't would
>>be tagged with a compiler error.  This might be problematic with
>>templates, as instantiation for a particular type may lead to non-pure
>>functions being called.

>Replace "pure" with "const".  It's no different.

In that case, pure would have to be part of the function
prototype(specification? Not sure if I'm using the right term here),
which would increase its impact on the language specification.  It
also means you could conceivably have both pure and impure (*) and
clean and unclean versions of the same function, though you could
restrict it to not allow this.

I suspect the standardization committee might be reluctant to make
such a change just for optimization reasons (especially at this
point), but maybe there will be a C++ '98 or some such.  (Gotta be,
for my wrappers proposal! :-)

Andrew Bell
abell@mindspring.com

* Although impure functions might be illegal in functions that might
be used by children because of the Exon Amendment....
---
[ 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: kanze@gabi-soft.fr (J. Kanze)
Date: 1996/04/09
Raw View
In article <4k7c9s$t5e@mule1.mindspring.com> abell@mindspring.com
(Andrew Bell) writes:

|> jbuck@Synopsys.COM (Joe Buck) wrote:
|>  >abell@mindspring.com (Andrew Bell) writes:
|> >>The problem is the compiler needs to know the "purity" of the
|> >>functions a given function calls during its compilation, or it can't
|> >>optimize the code.  You would thus have to compile all the called
|> >>functions first,

|> >No, you wouldn't.

|> Tsk, tsk, Joe, you misidentified someone else's statements as Jason's,
|> and then edited out the part I was responding to, thus making it look
|> like I was responding to something I wasn't.  I was responding to
|> Jason's comment that "pure" and "clean" as modifiers weren't necessary
|> with a slightly smarter compiler.  My response was that in that case,
|> all the code would have to be precompiled for purity/cleanliness,
|> before anything could be compiled, a statement I still stand by.

Concerning the qualification of `pure': I had considered a pragma for C
to this effect back when I was doing compiler work (late 80's).  In the
end, if I remember right, I decided that it wouldn't work, because most
of the functions you would want to label `pure' in fact aren't.  For
example, most of the mathematical functions (which was the main interest
at the time) aren't pure, because they may modify the global variable
`errno'.

I still think that the pragma idea has merit.  There are functions (like
exp or sqrt) that you want to the compiler to treat as pure, even though
they are not pure according to the strict rules.

|> >>With the proposed idea, a function that claims to pure and isn't would
|> >>be tagged with a compiler error.  This might be problematic with
|> >>templates, as instantiation for a particular type may lead to non-pure
|> >>functions being called.

|> >Replace "pure" with "const".  It's no different.

|> In that case, pure would have to be part of the function
|> prototype(specification? Not sure if I'm using the right term here),
|> which would increase its impact on the language specification.  It
|> also means you could conceivably have both pure and impure (*) and
|> clean and unclean versions of the same function, though you could
|> restrict it to not allow this.

To have both versions, you would have to have a criteria in order for
the compiler to select one or the other.  In this case, having both
would imply that any call to the function was, by definition, ambiguous.
So it is implicitly forbidden.  (Note that const/non-const is only valid
for member functions.)

|> I suspect the standardization committee might be reluctant to make
|> such a change just for optimization reasons (especially at this
|> point), but maybe there will be a C++ '98 or some such.  (Gotta be,
|> for my wrappers proposal! :-)

I am 99.9% certain that such a proposal will not be considered for the
current round of standardization.  It really is too late.  So it won't
make it into C++ '98.  (The year normally refers to the year in which
the standard is formally adapted.  so C++ '98 is about the earliest
possible for this round.)  How about C++ '05?
--
James Kanze           (+33) 88 14 49 00          email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs Bourgeois, 67000 Strasbourg, France
Conseils en informatique industrielle --
                            -- Beratung in industrieller Datenverarbeitung
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: martin@kcbbs.gen.nz (Martin D Kealey)
Date: 1996/04/01
Raw View
> Being const means only that the current function won't change the
> object, not that the object itself won't change during the function.
> It could change as the result of a side effect of another function
> called within the current one.

A non-const object can be changed any time its name or a non-const
pointer is in scope, through the name or pointer; this behaviour
is not surprising.  But as I understand it, there is no
dispensation to modify it through a const-pointer, which includes
"this".

> Thus unless only inline or other internally known functions are
> called, no additional optimizations are possible.

True, but only for the reason above, which is the same reason you
can't optimise away function calls in general.

What are needed (to allow some function calls to be optimised
away) are two new keywords:

  * "clean" which guarantees that the function doesn't modify
    objects that can only be reached as or through names
    in an outer scope - and in turn will not call any non-clean
    functions; and

  * "pure" which guarantees that the function does not depend on
    the value of any outer scope object - and in turn will not
    call any non-pure function;

To be fully useful, a function would be declared with both of
these attibutes and with all pointer or reference parameters
(including "this") declared "const".

Anyone care to put this forward, or has it been discussed before?
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: jdmorris@ix.netcom.com (Jason D. Morris)
Date: 1996/04/03
Raw View
On 01 Apr 1996 10:39:46 PST, martin@kcbbs.gen.nz (Martin D Kealey)
wrote:

>What are needed (to allow some function calls to be optimised
>away) are two new keywords:
>
>  * "clean" which guarantees that the function doesn't modify
>    objects that can only be reached as or through names
>    in an outer scope - and in turn will not call any non-clean
>    functions; and
>
>  * "pure" which guarantees that the function does not depend on
>    the value of any outer scope object - and in turn will not
>    call any non-pure function;
>
>To be fully useful, a function would be declared with both of
>these attibutes and with all pointer or reference parameters
>(including "this") declared "const".
>
>Anyone care to put this forward, or has it been discussed before?

Assuming you allow 'pure' and 'clean', the compiler would then have
to check to make sure your functions were in fact 'pure' and 'clean'.
If the compiler could do such checking as part of its array of
optimizations, why not just do it for every function as
part of a general optimization step?  If the compiler were to do
no checking for the adherence to 'pure' and 'clean' modifiers, then
such modifiers would essentially be a gentleman's contract.  Such
a "contract" could be freely violated with potentially disastrous
results; essentially making 'pure' and 'clean' meaningless.

Jason
---
[ 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: abell@mindspring.com (Andrew Bell)
Date: 1996/04/05
Raw View
jdmorris@ix.netcom.com (Jason D. Morris) wrote:
>Assuming you allow 'pure' and 'clean', the compiler would then have
>to check to make sure your functions were in fact 'pure' and 'clean'.
>If the compiler could do such checking as part of its array of
>optimizations, why not just do it for every function as
>part of a general optimization step?

The problem is the compiler needs to know the "purity" of the
functions a given function calls during its compilation, or it can't
optimize the code.  You would thus have to compile all the called
functions first, and have that information available while  you
compile that given function. For reasons I hope are reasonably
obvious, this is impossible.  Conceivably you could have a compilation
system that does a first pass compilation over all of the code,
looking for purity of functions, and then a second pass to do the
actual compilation, but that's a bit beyond the capabilities of most
modern compilers...

With the proposed idea, a function that claims to pure and isn't would
be tagged with a compiler error.  This might be problematic with
templates, as instantiation for a particular type may lead to non-pure
functions being called.  Also, changing a function so that it is no
longer pure may lead to a cascade of changes to other functions, as
they would lose their purity tag.  There are probably some other
problems I may not have noticed also (libraries that depend on other,
canging, libraries?)

Before making this part of the standard, it would be nice to have some
sample evidence of how much of a performance difference it makes in
meaningful programs.  In general, you can simulate this by saving in a
variable what you would use multiple calls to get (this is not as nice
for normal programming as having tags, however, as it would require
substantially more work to change if the called function is no longer
pure, or (even worse) might not get changed when it needs to be.

Andrew Bell
abell@mindspring.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: Philippe Verdy <100105.3120@compuserve.com>
Date: 1996/03/25
Raw View
Many recursive data structures require algorithms to handle
them which have to mark and unmark all scanned objects in
order to avoid infinite recursion when walking on that
structure, or when building items iterator.
Such algorithms will use the mark() and unmark() private
methods in each visited node, so that we can detect paths
which have already been visited. his is critical for example
when managing with auto-references, graphs, dictionnaries
of polymorphic objects (containing dictionnaries like in
a PostScript interpret).
However, how can we apply standard read-only methods on such
objects: these methods are specified as const in one of the
base classes, and virtual override requires not to change the
constness of the derived object.
So we cannot mark such structures, because even a private
member cannot be modified in a const instance.
We can effectively change temporarily the constness of the
object to realize this mark, but in that case we would write
the following :
  class T {
  public:
    T()                   { ...; _mark = 0; }
    virtual ~T();

    virtual void show() const;
  protected:
    void mark()           { _mark = 1; }
    void unmark()         { _mark = 0; }
    bool ismarked() const { return _mark; }
  private:
    char _mark;
  }
The problem is that now mark() and unmark() methods are not
const so they cannot be used in read-only methods like show().
So we have to use a const_cast<T&> or const_cast<T*> to
suppress this constness.

This is not obvious, and has the big disadvantage of globally
suppressing the constness of the object. So this is quite
dangerous, because some-times, we do not know really if a
method has an impact on the semantic value of the instance
on which we apply this cast. So this is a security hole which
should be avoided.

We can avoid const_casting to call mark() and unmark() by
declaring them as const, like this:
  protected:
    void mark() const   { (const_cast<T*>this)->_mark = 1; }
    void unmark() const { (const_cast<T*>this)->_mark = 0; }
but this is really hard to write, and is it semantically
correct ? It would from the public point of view, but what
on the private point of view ?

We can also use explicitly (const_cast<T*>this)->mark(); and
(const_cast<T*>this)->unmark(); calls in the show()
implementation, but this is quite hard to write, so that many
users refrain using const specifiers on their classes.

Is there any way (or proposal) to explicitly specify members
of a class definition which are relaxed on constness certi-
fication ?

Would not it be great if we could simply define such members
as "unconst" like in the following example :

  class T {
  public:
    T()                   { ...; _mark = 0; }
    virtual ~T();

    virtual void show() const;
  protected:
    void mark() const     { _mark = 1; } // RELAXED HERE
    void unmark() const   { _mark = 0; } // RELAXED HERE
    bool ismarked() const { return _mark; }
  private:
    unconst char _mark; // HERE IS WHERE THIS APPLIES
  }

In that example, even thow the mark() and unmark() methods
are const-specified, we are allowed to modify the _mark
member, because it has been explicitly relaxed.

We could restrict the unconst modifier usage to private
or protected members declaration only, so that the public
interface of a class would keep the constness integrity.

This way, the dangerous const_cast<> operator could be avoided
most of the time and isolated in specific class
implementations (for compatibility with not const-compliant
C libraries)...

What do you think ?

And is constness definition a semantic only definition,
or does it involve a more strict sense in which the compiler
optimizer would have an influence (such as in common
subexpressions reduction) ?
---
[ comp.std.c++ is moderated.  To submit articles: Try just posting with your
                newsreader.  If that fails, use mailto:std-c++@ncar.ucar.edu
  comp.std.c++ FAQ: http://reality.sgi.com/austern/std-c++/faq.html
  Moderation policy: http://reality.sgi.com/austern/std-c++/policy.html
  Comments? mailto:std-c++-request@ncar.ucar.edu
]





Author: kuehl@uzwil.informatik.uni-konstanz.de (Dietmar Kuehl)
Date: 1996/03/26
Raw View
Hi,

Philippe Verdy (100105.3120@compuserve.com) wrote:
[lengthy description of problems with bitwise instead of logical
constness elided]

: Is there any way (or proposal) to explicitly specify members
: of a class definition which are relaxed on constness certi-
: fication ?

Yes: it is possible to declare a data member of an object to be
'mutable'.  This allows to modify this member even in a 'const'
function. The main idea which leads to a reasonable use of 'mutable' is
the concept of logical versus bitwise constness: In C++ bitwise
constness is generally assumed. You cannot change the member of a
constant object. However, sometimes this is not what you want (auxilary
marks and cached values are two examples).  Instead, logical constness
is desired: The representation of the object might change but the value
represented stays the same. Note, however, that the language does not
(and can not) enforce that logical constness is maintained if the
object has mutable members. It is the responsibility of the programmer
to ensure logical constness.

: Would not it be great if we could simply define such members
: as "unconst" like in the following example :

:   class T {
:   public:
:     T()                   { ...; _mark = 0; }
:     virtual ~T();

:     virtual void show() const;
:   protected:
:     void mark() const     { _mark = 1; } // RELAXED HERE
:     void unmark() const   { _mark = 0; } // RELAXED HERE
:     bool ismarked() const { return _mark; }
:   private:
:     unconst char _mark; // HERE IS WHERE THIS APPLIES
:   }

If you replace 'unconst' by 'mutable' you have what will become
standard. Since the 'mutable' keyword is a recent addition to the
DWP, it is not yet supported by all compilers.
--
dietmar.kuehl@uni-konstanz.de
http://www.informatik.uni-konstanz.de/~kuehl
I am a realistic optimist - that's why I appear to be slightly pessimistic
---
[ 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: Rob Stewart <stew@datalytics.com>
Date: 1996/03/26
Raw View
Philippe Verdy wrote:
>
> Many recursive data structures require algorithms to handle
> them which have to mark and unmark all scanned objects in
> order to avoid infinite recursion when walking on that
> structure, or when building items iterator.
> Such algorithms will use the mark() and unmark() private
> methods in each visited node, so that we can detect paths
> which have already been visited. his is critical for example
> when managing with auto-references, graphs, dictionnaries
> of polymorphic objects (containing dictionnaries like in
> a PostScript interpret).
> However, how can we apply standard read-only methods on such
> objects: these methods are specified as const in one of the
> base classes, and virtual override requires not to change the
> constness of the derived object.
> So we cannot mark such structures, because even a private
> member cannot be modified in a const instance.
> We can effectively change temporarily the constness of the
> object to realize this mark, but in that case we would write
> the following :[snip]
> The problem is that now mark() and unmark() methods are not
> const so they cannot be used in read-only methods like show().
> So we have to use a const_cast<T&> or const_cast<T*> to
> suppress this constness.
>
> This is not obvious, and has the big disadvantage of globally
> suppressing the constness of the object. So this is quite
> dangerous, because some-times, we do not know really if a
> method has an impact on the semantic value of the instance
> on which we apply this cast. So this is a security hole which
> should be avoided.
>
> We can avoid const_casting to call mark() and unmark() by
> declaring them as const, like this:[snip]
> but this is really hard to write, and is it semantically
> correct ? It would from the public point of view, but what
> on the private point of view ?
>
> We can also use explicitly (const_cast<T*>this)->mark(); and
> (const_cast<T*>this)->unmark(); calls in the show()
> implementation, but this is quite hard to write, so that many
> users refrain using const specifiers on their classes.
> [snip]
> What do you think ?
>
> And is constness definition a semantic only definition,
> or does it involve a more strict sense in which the compiler
> optimizer would have an influence (such as in common
> subexpressions reduction) ?

There are two schools of thought regarding const-ness.  One
requires strict bitwise constness.  That means that if you
construct a const object, did a memcpy of the object to some
suitable buffer, exercised the object using any permissible
(const) mfs, in any combination, then compared the object with
the memcpy'd buffer, there would be no change.

The other requires only logical constness.  That means that the
object always appears the same through its public and protected
interfaces.  You can do what you want inside the object,
provided it always appears the same to the class user.

The compiler obviously enforces the former definition.  You must
cast away constness when you want the latter.  That definition
is the one you're employing here.

According to how you've described mark and unmark, they must be
controlled by other functions such that the original state is
restored before return to the caller.  That is, some other
function must use mark and unmark, in matched sets for each
node, in order to preserve the external state of the object.

Therefore, it is not mark and unmark which should cast away
constness, but those functions that make use of them.  mark and
unmark should be non-const; they each change the state in a way
that affects the external state of the class.  Those functions
calling them must cast away constness to use them.

As for your question about some language extension to permit
that behavior, it could only apply to functions calling mark and
unmark in their use of them.  That is, since only
functions using mark and unmark can ensure that the
original state is restored--thus preserving the logical
constness--only they can be used on const objects.  Therefore,
they should be the ones to get special dispensation to use
non-const mfs in such a way that they retain logical constness.

The difficulty is with maintenance.  Sure, after some design and
debugging work, you can get the functions to work correctly such
that you retain logical constness.  The maintainer of your code
may have more trouble or may not realize the consequence of his
actions, and destroy logical constness.  Once you violate the
bitwise constness of the compiler, you're on your own.  This is
true of casting away constness yourself, but would we really
want a language feature which makes it easy and makes less clear
where special attention is required?

I don't think so.  Instead, you should consider how to build a
base class that encapsulates the iteration process to which you
can pass a derived class mf to process each node you encounter.
The implementation will appear once in your code and shouldn't
require maintenance once you fix the bugs.  All the rest of your
code that needs to iterate the container will make use of that
base class functionality, but won't need to worry about casting
away constness.

--
Robert Stewart  | My opinions are usually my own.
Datalytics, Inc. | stew@datalytics.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: abell@mindspring.com (Andrew Bell)
Date: 1996/03/26
Raw View
Philippe Verdy <100105.3120@compuserve.com> wrote:

>Many recursive data structures require algorithms to handle
>them which have to mark and unmark all scanned objects in
>order to avoid infinite recursion when walking on that
>structure, or when building items iterator.

The property of being marked is really part of your algorithm, not
part of the object itself.  You should consider making some sort of
separate record (a list of some sort) to indicate which items are
marked and unmarked.  Otherwise, you'll then find an algorithm where
you have to mark things twice, and so on...

>Is there any way (or proposal) to explicitly specify members
>of a class definition which are relaxed on constness certi-
>fication ?

Sounds like "mutable" to me.

>And is constness definition a semantic only definition,

Being const means only that the current function won't change the
object, not that the object itself won't change during the function.
It could change as the result of a side effect of another function
called within the current one.  Thus unless only inline or other
internally known functions are called, no additional optimizations are
possible.

Andrew Bell
abell@mindspring.com
---
[ comp.std.c++ is moderated.  To submit articles: try just posting with      ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu         ]
[ FAQ:      http://reality.sgi.com/employees/austern_mti/std-c++/faq.html    ]
[ Policy:   http://reality.sgi.com/employees/austern_mti/std-c++/policy.html ]
[ Comments? mailto:std-c++-request@ncar.ucar.edu                             ]





Author: clamage@Eng.sun.com (Steve Clamage)
Date: 1996/03/26
Raw View
In article 8fo@dub-news-svc-4.compuserve.com, Philippe Verdy

>Is there any way (or proposal) to explicitly specify members
>of a class definition which are relaxed on constness certi-
>fication ?
>
>Would not it be great if we could simply define such members
>as "unconst" like in the following example :

The C++ draft standard has for some time included the keyword "mutable".
A mutable data member may be modified by any member function,
even if the object or the member function is const.

---
Steve Clamage, stephen.clamage@eng.sun.com




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





Author: kanze@lts.sel.alcatel.de (James Kanze US/ESC 60/3/141 #40763)
Date: 1996/03/26
Raw View
In article <4j49e0$8fo@dub-news-svc-4.compuserve.com> Philippe Verdy
<100105.3120@compuserve.com> writes:

|> Would not it be great if we could simply define such members
|> as "unconst" like in the following example :

|>   class T {
|>   public:
|>     T()                   { ...; _mark = 0; }
|>     virtual ~T();

|>     virtual void show() const;
|>   protected:
|>     void mark() const     { _mark = 1; } // RELAXED HERE
|>     void unmark() const   { _mark = 0; } // RELAXED HERE
|>     bool ismarked() const { return _mark; }
|>   private:
|>     unconst char _mark; // HERE IS WHERE THIS APPLIES
|>   }

You can.  Except that `unconst' is spelled `mutable'.
--
James Kanze         Tel.: (+33) 88 14 49 00        email: kanze@gabi-soft.fr
GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
Conseils,    tudes et r   alisations en logiciel orient    objet --
                -- A la recherche d'une activit    dans une region francophone



[ comp.std.c++ is moderated.  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                             ]