By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,007 Members | 979 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,007 IT Pros & Developers. It's quick & easy.

C++ Pitfall: const objects do not behave constantly.

P: n/a
It is erroneous to think that const objects will have constant behaviors too.

Consider the following snip of code:

class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random strings.
return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is immutable.

// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.

This also means that compiler cannot make optimizations with const object.

So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other member
functions, (those that are not declared 'const'). No other conditions
can be assumed.

--

-kira

Sep 25 '07 #1
Share this Question
Share on Google+
23 Replies


P: n/a
Kira Yamato wrote:
It is erroneous to think that const objects will have constant
behaviors too.
What is your definition of "constant behaviour"?
>
Consider the following snip of code:

class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random
strings. return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is
immutable.
// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.
Is it possible that you think somebody can confuse immutability with
repeatability?
This also means that compiler cannot make optimizations with const
object.
How do you make that leap? And what optimizations are we talking
here?
So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other
member functions, (those that are not declared 'const'). No other
conditions can be assumed.
That's pretty much the actual defintion of 'const'. Have you been
reading some book or article that says otherwise? Then please quote.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 25 '07 #2

P: n/a
On 2007-09-25 17:00:16 -0400, "Victor Bazarov" <v.********@comAcast.netsaid:
Kira Yamato wrote:
>It is erroneous to think that const objects will have constant
behaviors too.

What is your definition of "constant behaviour"?
I was thinking of it as a state machine. If the state remains the
same, then equal inputs should produce equal outputs.

In my example, I was expecting the two instances of invocations of
get_name() to return the same thing.
>
>>
Consider the following snip of code:

class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random
strings. return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is
immutable.
// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.

Is it possible that you think somebody can confuse immutability with
repeatability?
Apparently so. I was thinking what the *intented* use of the keyword
'const' is. I thought it was intented to be so that things declared
'const' should yield repeatable results.
>
>This also means that compiler cannot make optimizations with const
object.

How do you make that leap? And what optimizations are we talking
here?
For example, if indeed it were treated like a state machine (so that
unchanged states should yield unchanged responses from 'const'
functions), then the compiler can remove the 2nd invocation of
get_name() and just use the result from the first invocation.
>
>So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other
member functions, (those that are not declared 'const'). No other
conditions can be assumed.

That's pretty much the actual defintion of 'const'. Have you been
reading some book or article that says otherwise? Then please quote.
Nowhere says that. I'm learning C++ mostly by examples from other
people's code. So, I'm mostly just guessing what each part of the
language is doing, and learning by trials and errors.

So, I suppose in this case coining this mechanism by the keyword
'const' is a poor choice, even though that is where it finds most
applications in. However, keywords should be chosen for what it
actually does instead of what it is intended to do. In the case of
'const', these two things are clearly not the same thing.
>
V
--

-kira

Sep 25 '07 #3

P: n/a
On 2007-09-25 22:37, Kira Yamato wrote:
It is erroneous to think that const objects will have constant behaviors too.

Consider the following snip of code:
Please consider replacing tabs with a few spaces when posting.
class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random strings.
return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is immutable.

// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.

This also means that compiler cannot make optimizations with const object.

So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other member
functions, (those that are not declared 'const'). No other conditions
can be assumed.
I would hardly call this a pitfall, and I have yet to meat anyone with a
bit of OO programming skill who fail to grasp the concept of constant
objects (namely that their state are constant/unchangeable). Personally
I think that the const concept is a really powerful one, especially when
parring arguments to functions. As an example when I as a programmer use
a third party API I know that I can safely pass any string I have to a
function taking a const string reference as parameter, since the string
will not be changed by the function. Without const I would not have that
guarantee and I would have to make a copy and pass that to be safe.

--
Erik Wikström
Sep 25 '07 #4

P: n/a
Kira Yamato wrote:
On 2007-09-25 17:00:16 -0400, "Victor Bazarov"
<v.********@comAcast.netsaid:
>Kira Yamato wrote:
>>It is erroneous to think that const objects will have constant
behaviors too.

What is your definition of "constant behaviour"?

I was thinking of it as a state machine. If the state remains the
same, then equal inputs should produce equal outputs.

In my example, I was expecting the two instances of invocations of
get_name() to return the same thing.
I am not sure what the basis of this is. Objects (in C++) are not
necessarily state machines. They are just objects. Anything that
is declared 'const' does not change. However, there is no guarantee
that it would not produce different output for the same input, those
things are totally orthogonal. Just like you've shown.
>[..]
>>This also means that compiler cannot make optimizations with const
object.

How do you make that leap? And what optimizations are we talking
here?

For example, if indeed it were treated like a state machine (so that
unchanged states should yield unchanged responses from 'const'
functions), then the compiler can remove the 2nd invocation of
get_name() and just use the result from the first invocation.
Yes, and if the grandmother had b***s, she would be the grandfather.
Sorry for the rude analogy, but that's what you seem to have here --
you make up some dependency and then try to draw some conclusions
from it. And you seem surprised (disclaimer: I may have simply
misinterpreted your reaction).
>>So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other
member functions, (those that are not declared 'const'). No other
conditions can be assumed.

That's pretty much the actual defintion of 'const'. Have you been
reading some book or article that says otherwise? Then please quote.

Nowhere says that. I'm learning C++ mostly by examples from other
people's code. So, I'm mostly just guessing what each part of the
language is doing, and learning by trials and errors.
That's a bad way to learn a programming language. Trust me.
So, I suppose in this case coining this mechanism by the keyword
Coining *what* mechanism?
'const' is a poor choice, even though that is where it finds most
applications in. However, keywords should be chosen for what it
actually does instead of what it is intended to do. In the case of
'const', these two things are clearly not the same thing.
Here is another pitfall for you:

class HasOther {
OtherObject *ptr;
public:
HasOther(OtherObject *p) : ptr(new OtherObject) {}
void Gotcha(OtherObject const& value) const
{
if (ptr) *ptr = value;
}
};

In the 'Gotcha' function, which is declared 'const', the 'HasOther'
without _any_problem_ changes the value of the object to which it
refers, even though the 'HasOther' is constant. It has nothing to
do with behavour, but /some/ people would actually thing that the
value of the object to which 'ptr' points should also be constant.
It isn't.

Beware of the results you get from *expecting* something instead of
*learning* how it actually is.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 25 '07 #5

P: n/a
On 2007-09-25 17:32:26 -0400, Erik Wikström <Er***********@telia.comsaid:
On 2007-09-25 22:37, Kira Yamato wrote:
>It is erroneous to think that const objects will have constant behaviors too.

Consider the following snip of code:

Please consider replacing tabs with a few spaces when posting.
>class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random strings.
return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is immutable.

// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.

This also means that compiler cannot make optimizations with const object.

So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other member
functions, (those that are not declared 'const'). No other conditions
can be assumed.

I would hardly call this a pitfall, and I have yet to meat anyone with a
bit of OO programming skill who fail to grasp the concept of constant
objects (namely that their state are constant/unchangeable).
What is the state of an object? A state of an object is supposed to be
a set of data that determines the behavior of an object. In another
word, knowing the state of an object would dictate what its functions
do given some inputs. Otherwise, what is the point of knowing an
object's state?

So, if you say that declaring an object 'const' should keep its state
constant, then its member functions should yield the same output for
the same input since the object remains in the same state!

However, this is not the case as shown in the example.

This is the pitfall.

Rigorously, all 'const' really does is that it is a switch to disable
the invocation of certain member functions --- those that are not
declared 'const'.
Personally
I think that the const concept is a really powerful one, especially when
parring arguments to functions. As an example when I as a programmer use
a third party API I know that I can safely pass any string I have to a
function taking a const string reference as parameter, since the string
will not be changed by the function. Without const I would not have that
guarantee and I would have to make a copy and pass that to be safe.
I do agree that the idea of guaranteeing an object's state be constant
is a powerful one. I'm just saying the actual use of 'const' is not
that. In essence, it is just an agreement of the API that it will not
invoke certain member functions (those that are not declared 'const')
of the object passed to it.

Rather or not the object declared 'const' will really keep its state
constant is depended upon what the class actually implements. In my
example, it does not do that, even though I've used 'const'.

--

-kira

Sep 25 '07 #6

P: n/a
On 2007-09-25 18:08:29 -0400, Kira Yamato <ki*****@earthlink.netsaid:
>
Rigorously, all 'const' really does is that it is a switch to disable
the invocation of certain member functions --- those that are not
declared 'const'.
It also prevents modification of data members that aren't marked
"mutable". Those data members are the object's state.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

Sep 25 '07 #7

P: n/a
On Sep 25, 4:24 pm, Kira Yamato <kira...@earthlink.netwrote:
On 2007-09-25 17:00:16 -0400, "Victor Bazarov" <v.Abaza...@comAcast.netsaid:
Kira Yamato wrote:
(...)
So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other
member functions, (those that are not declared 'const'). No other
conditions can be assumed.
(...)
>
So, I suppose in this case coining this mechanism by the keyword
'const' is a poor choice, even though that is where it finds most
applications in. However, keywords should be chosen for what it
actually does instead of what it is intended to do. In the case of
'const', these two things are clearly not the same thing.
Stroustrup had initially chosen 'readonly' as the keyword. Later, he
decided to replace it with 'const'.

There is some (very little) background here:
http://www.research.att.com/~bs/bs_f...constplacement

Check out "Design and Evolution of C++" for more details.

- Anand

Sep 25 '07 #8

P: n/a

"Kira Yamato" <ki*****@earthlink.netwrote in message
news:2007092516373416807-kirakun@earthlinknet...
It is erroneous to think that const objects will have constant behaviors
too.

Consider the following snip of code:

class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random strings.
return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is immutable.

// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.

This also means that compiler cannot make optimizations with const object.

So to me, declaring an object 'const' is really just a mechanism to allow
a certain subset of the object's member functions to be called (those that
are declared 'const') and disallow calling the other member functions,
(those that are not declared 'const'). No other conditions can be
assumed.
I believe you are confusing the word "constant" with "consistant". The
const keyword says change any of the objects variables. The result from
get_name() is not a variable. It is a function and can do anything. Notice
that get_name is declared const, it does not change any of the objects
variables. The variables with in the object remain constant, they do not
change. Output, however, may not be consistant depending on what the
methods do.
Sep 25 '07 #9

P: n/a
Kira Yamato wrote:
>
Rigorously, all 'const' really does is that it is a switch to disable
the invocation of certain member functions --- those that are not
declared 'const'.
Wrong. Or at least incomplete. const is not an arbitrary label that
can be applied to any member function. The compiler will not let you
declare a member function constant if it attempts to perform
non-constant actions, including modifying the class member variables.

This whole argument is really quite silly since, as Victor pointed out,
it all stems from your confusion over the difference between constant
and repeatable.
Sep 25 '07 #10

P: n/a
On 2007-09-26 00:08, Kira Yamato wrote:
On 2007-09-25 17:32:26 -0400, Erik Wikström <Er***********@telia.comsaid:
>On 2007-09-25 22:37, Kira Yamato wrote:
>>So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other member
functions, (those that are not declared 'const'). No other conditions
can be assumed.

I would hardly call this a pitfall, and I have yet to meat anyone with a
bit of OO programming skill who fail to grasp the concept of constant
objects (namely that their state are constant/unchangeable).

What is the state of an object? A state of an object is supposed to be
a set of data that determines the behavior of an object. In another
word, knowing the state of an object would dictate what its functions
do given some inputs. Otherwise, what is the point of knowing an
object's state?

So, if you say that declaring an object 'const' should keep its state
constant, then its member functions should yield the same output for
the same input since the object remains in the same state!

However, this is not the case as shown in the example.
You would be right provided that the results (return values and side
effects) of the member functions were totally dependent on the object's
state. In the example above this is not the case, and there is thus no
need to for the results to be the same. Consider the following:

#include <iostream>

struct Foo
{
int bar(int i) const
{
return i;
}
};

int main()
{
const Foo f;
std::cout << f.bar(1) << "\n";
std::cout << f.bar(2) << "\n";
}

By your reasoning both calls to bar() should return the same thing, but
that would be totally illogical.

--
Erik Wikström
Sep 26 '07 #11

P: n/a
On 2007-09-25 19:00:31 -0400, "Jim Langston" <ta*******@rocketmail.comsaid:
>
"Kira Yamato" <ki*****@earthlink.netwrote in message
news:2007092516373416807-kirakun@earthlinknet...
>It is erroneous to think that const objects will have constant behaviors
too.

Consider the following snip of code:

class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random strings.
return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is immutable.

// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.

This also means that compiler cannot make optimizations with const object.

So to me, declaring an object 'const' is really just a mechanism to allow
a certain subset of the object's member functions to be called (those that
are declared 'const') and disallow calling the other member functions,
(those that are not declared 'const'). No other conditions can be
assumed.

I believe you are confusing the word "constant" with "consistant". The
const keyword says change any of the objects variables. The result from
get_name() is not a variable. It is a function and can do anything. Notice
that get_name is declared const, it does not change any of the objects
variables. The variables with in the object remain constant, they do not
change. Output, however, may not be consistant depending on what the
methods do.
I know. And hence I named this a pitfall.

However, I'm starting to get the sense that this is a pitfall for
newbies only. Seems like everyone else has no problem with it except
me. :)

--

-kira

Sep 26 '07 #12

P: n/a
On 2007-09-25 17:45:11 -0400, "Victor Bazarov" <v.********@comAcast.netsaid:
Kira Yamato wrote:
>On 2007-09-25 17:00:16 -0400, "Victor Bazarov"
<v.********@comAcast.netsaid:
>>Kira Yamato wrote:
It is erroneous to think that const objects will have constant
behaviors too.

What is your definition of "constant behaviour"?

I was thinking of it as a state machine. If the state remains the
same, then equal inputs should produce equal outputs.

In my example, I was expecting the two instances of invocations of
get_name() to return the same thing.

I am not sure what the basis of this is. Objects (in C++) are not
necessarily state machines. They are just objects. Anything that
is declared 'const' does not change. However, there is no guarantee
that it would not produce different output for the same input, those
things are totally orthogonal. Just like you've shown.
Right. This is the lesson I learned here.
>
>>[..]
This also means that compiler cannot make optimizations with const
object.

How do you make that leap? And what optimizations are we talking
here?

For example, if indeed it were treated like a state machine (so that
unchanged states should yield unchanged responses from 'const'
functions), then the compiler can remove the 2nd invocation of
get_name() and just use the result from the first invocation.

Yes, and if the grandmother had b***s, she would be the grandfather.
Sorry for the rude analogy, but that's what you seem to have here --
you make up some dependency and then try to draw some conclusions
from it. And you seem surprised (disclaimer: I may have simply
misinterpreted your reaction).
lol. I don't know where that came from, but I had a good chuckle out of it.
>
>>>So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other
member functions, (those that are not declared 'const'). No other
conditions can be assumed.

That's pretty much the actual defintion of 'const'. Have you been
reading some book or article that says otherwise? Then please quote.

Nowhere says that. I'm learning C++ mostly by examples from other
people's code. So, I'm mostly just guessing what each part of the
language is doing, and learning by trials and errors.

That's a bad way to learn a programming language. Trust me.
>So, I suppose in this case coining this mechanism by the keyword

Coining *what* mechanism?
>'const' is a poor choice, even though that is where it finds most
applications in. However, keywords should be chosen for what it
actually does instead of what it is intended to do. In the case of
'const', these two things are clearly not the same thing.

Here is another pitfall for you:

class HasOther {
OtherObject *ptr;
public:
HasOther(OtherObject *p) : ptr(new OtherObject) {}
void Gotcha(OtherObject const& value) const
{
if (ptr) *ptr = value;
}
};

In the 'Gotcha' function, which is declared 'const', the 'HasOther'
without _any_problem_ changes the value of the object to which it
refers, even though the 'HasOther' is constant. It has nothing to
do with behavour, but /some/ people would actually thing that the
value of the object to which 'ptr' points should also be constant.
It isn't.
Yea. This could be classified as an example of bad design. Clearly,
part of the state of the object is placed outside the object in another
external object. In this way, it bypasses the mechanism 'const'.
>
Beware of the results you get from *expecting* something instead of
*learning* how it actually is.

V
A very good point to keep in mind when programming. What we code is
not always what we intended.

--

-kira

Sep 26 '07 #13

P: n/a
On Sep 25, 3:08 pm, Kira Yamato <kira...@earthlink.netwrote:
On 2007-09-25 17:32:26 -0400, Erik Wikström <Erik-wikst...@telia.comsaid:


On 2007-09-25 22:37, Kira Yamato wrote:
It is erroneous to think that const objects will have constant behaviors too.
Consider the following snip of code:
Please consider replacing tabs with a few spaces when posting.
class Person
{
public:
Person();
string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random strings.
return dice.getRandomString();
}
void set_name(const string &name);
};
void func(const Person &person)
{
// note that the object 'person' is declared const, so it is immutable.
// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.
// print one name here,
cout << person.get_name() << endl;
// but it could print a different name here.
cout << person.get_name() << endl;
}
Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.
This also means that compiler cannot make optimizations with const object.
So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other member
functions, (those that are not declared 'const'). No other conditions
can be assumed.
I would hardly call this a pitfall, and I have yet to meat anyone with a
bit of OO programming skill who fail to grasp the concept of constant
objects (namely that their state are constant/unchangeable).

What is the state of an object? A state of an object is supposed to be
a set of data that determines the behavior of an object. In another
word, knowing the state of an object would dictate what its functions
do given some inputs. Otherwise, what is the point of knowing an
object's state?

So, if you say that declaring an object 'const' should keep its state
constant, then its member functions should yield the same output for
the same input since the object remains in the same state!
YOU are the one that declared the get_name() method as const. It is
literally bitwise const, but not really stateful const. If that
matters to your app - DO NOT DECLARE IT AS CONST.

Sep 26 '07 #14

P: n/a
On 2007-09-26 06:32, Kira Yamato wrote:
On 2007-09-25 17:45:11 -0400, "Victor Bazarov" <v.********@comAcast.netsaid:
>Kira Yamato wrote:
>>On 2007-09-25 17:00:16 -0400, "Victor Bazarov"
<v.********@comAcast.netsaid:
Kira Yamato wrote:
It is erroneous to think that const objects will have constant
behaviors too.

What is your definition of "constant behaviour"?

I was thinking of it as a state machine. If the state remains the
same, then equal inputs should produce equal outputs.

In my example, I was expecting the two instances of invocations of
get_name() to return the same thing.

I am not sure what the basis of this is. Objects (in C++) are not
necessarily state machines. They are just objects. Anything that
is declared 'const' does not change. However, there is no guarantee
that it would not produce different output for the same input, those
things are totally orthogonal. Just like you've shown.

Right. This is the lesson I learned here.
>>
>>>[..]
This also means that compiler cannot make optimizations with const
object.

How do you make that leap? And what optimizations are we talking
here?

For example, if indeed it were treated like a state machine (so that
unchanged states should yield unchanged responses from 'const'
functions), then the compiler can remove the 2nd invocation of
get_name() and just use the result from the first invocation.

Yes, and if the grandmother had b***s, she would be the grandfather.
Sorry for the rude analogy, but that's what you seem to have here --
you make up some dependency and then try to draw some conclusions
from it. And you seem surprised (disclaimer: I may have simply
misinterpreted your reaction).

lol. I don't know where that came from, but I had a good chuckle out of it.
>>
>>>>So to me, declaring an object 'const' is really just a mechanism to
allow a certain subset of the object's member functions to be called
(those that are declared 'const') and disallow calling the other
member functions, (those that are not declared 'const'). No other
conditions can be assumed.

That's pretty much the actual defintion of 'const'. Have you been
reading some book or article that says otherwise? Then please quote.

Nowhere says that. I'm learning C++ mostly by examples from other
people's code. So, I'm mostly just guessing what each part of the
language is doing, and learning by trials and errors.

That's a bad way to learn a programming language. Trust me.
>>So, I suppose in this case coining this mechanism by the keyword

Coining *what* mechanism?
>>'const' is a poor choice, even though that is where it finds most
applications in. However, keywords should be chosen for what it
actually does instead of what it is intended to do. In the case of
'const', these two things are clearly not the same thing.

Here is another pitfall for you:

class HasOther {
OtherObject *ptr;
public:
HasOther(OtherObject *p) : ptr(new OtherObject) {}
void Gotcha(OtherObject const& value) const
{
if (ptr) *ptr = value;
}
};

In the 'Gotcha' function, which is declared 'const', the 'HasOther'
without _any_problem_ changes the value of the object to which it
refers, even though the 'HasOther' is constant. It has nothing to
do with behavour, but /some/ people would actually thing that the
value of the object to which 'ptr' points should also be constant.
It isn't.

Yea. This could be classified as an example of bad design. Clearly,
part of the state of the object is placed outside the object in another
external object. In this way, it bypasses the mechanism 'const'.
No, one again you confuse what the state of the object is. The state of
the HasOther object is that it knows of another object of type
OtherObject. Changing the state of the OtherObject does not affect the
state of the HasOther object, just the state of OtherObject.

Think of it like this, if I have a fried and that friend changes his/her
hair-colour it does not mean that I have changed in any way. The
friendship is the pointer above, it creates a relation between me and my
friend. It does not however make him/her a part of me.

--
Erik Wikström
Sep 26 '07 #15

P: n/a
On 2007-09-26 06:29, Kira Yamato wrote:
On 2007-09-25 19:00:31 -0400, "Jim Langston" <ta*******@rocketmail.comsaid:
>>
"Kira Yamato" <ki*****@earthlink.netwrote in message
news:2007092516373416807-kirakun@earthlinknet...
>>It is erroneous to think that const objects will have constant behaviors
too.

Consider the following snip of code:

class Person
{
public:
Person();

string get_name() const
{
Randomizer dice; // Randomizer is some class that returns random strings.
return dice.getRandomString();
}

void set_name(const string &name);
};

void func(const Person &person)
{
// note that the object 'person' is declared const, so it is immutable.

// However, the following two lines can print different names,
// even though we are invoking const member function 'getName'.

// print one name here,
cout << person.get_name() << endl;

// but it could print a different name here.
cout << person.get_name() << endl;
}

Thus, object behavior is not guarantee to be constant for const object
even though its state is unchanged.

This also means that compiler cannot make optimizations with const object.

So to me, declaring an object 'const' is really just a mechanism to allow
a certain subset of the object's member functions to be called (those that
are declared 'const') and disallow calling the other member functions,
(those that are not declared 'const'). No other conditions can be
assumed.

I believe you are confusing the word "constant" with "consistant". The
const keyword says change any of the objects variables. The result from
get_name() is not a variable. It is a function and can do anything. Notice
that get_name is declared const, it does not change any of the objects
variables. The variables with in the object remain constant, they do not
change. Output, however, may not be consistant depending on what the
methods do.

I know. And hence I named this a pitfall.

However, I'm starting to get the sense that this is a pitfall for
newbies only. Seems like everyone else has no problem with it except
me. :)
I would suspect that this stems from the fact that you have not had any
formal teaching or even read a book. Normally const is introduced on
simple variables first and then the concept is extended to classes. I
would suggest that you get yourself a good book and start reading that.
Many recommend Accelerated C++ by Koenig & Moe, Thinking in C++ by Bruce
Eckel is available for free on the net (just search for it).

--
Erik Wikström
Sep 26 '07 #16

P: n/a
On Sep 25, 11:24 pm, Kira Yamato <kira...@earthlink.netwrote:
On 2007-09-25 17:00:16 -0400, "Victor Bazarov" <v.Abaza...@comAcast.netsaid:
Kira Yamato wrote:
It is erroneous to think that const objects will have constant
behaviors too.
What is your definition of "constant behaviour"?
I was thinking of it as a state machine. If the state remains the
same, then equal inputs should produce equal outputs.
Why?

When the output is defined as being independant of the state,
why would you expect that it depend on the state? If there's an
error in your code, it's making the function you called a
member, since the function has nothing to do with the class.
But that's neither here nor there: one could easily imagine a
"valueAtTime" function which returned a compound value
(formatted string, struct, whatever) which contained some
internal value and the current time. Such a function should be
const because it doesn't change the observable state of the
object. And of course, the current time isn't part of the
observable state of the object, even if it is part of the return
value of some member function.
In my example, I was expecting the two instances of
invocations of get_name() to return the same thing.
Again, why?

[...]
Thus, object behavior is not guarantee to be constant for
const object even though its state is unchanged.
Is it possible that you think somebody can confuse
immutability with repeatability?
Apparently so. I was thinking what the *intented* use of the
keyword 'const' is. I thought it was intented to be so that
things declared 'const' should yield repeatable results.
This also means that compiler cannot make optimizations
with const object.
How do you make that leap? And what optimizations are we
talking here?
For example, if indeed it were treated like a state machine
(so that unchanged states should yield unchanged responses
from 'const' functions),
The only "state machine" in this sense is the complete computer.
then the compiler can remove the 2nd invocation of get_name()
and just use the result from the first invocation.
In other words, that the function is pure. Pure is a lot
stronger than const.
So, I suppose in this case coining this mechanism by the
keyword 'const' is a poor choice, even though that is where it
finds most applications in. However, keywords should be
chosen for what it actually does instead of what it is
intended to do. In the case of 'const', these two things are
clearly not the same thing.
There is a potential problem with const, in that the language
specifies bitwise const, where as the usual use is logical
const. But the keyword const suggests (in my mind, at least)
constant, not pure. A const function does not change the
(visible) state of the object it is called on. Which seems to
be the usual way it is used, as well. You seem to be confusing
const with pure.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 26 '07 #17

P: n/a
On Sep 26, 11:04 am, Erik Wikström <Erik-wikst...@telia.comwrote:
On 2007-09-26 06:32, Kira Yamato wrote:
No, one again you confuse what the state of the object is. The state of
the HasOther object is that it knows of another object of type
OtherObject. Changing the state of the OtherObject does not affect the
state of the HasOther object, just the state of OtherObject.
It depends. A long time ago (around 15 years), there were great
debates over logical const vs. bitwise const: I once said
something along the lines of "so const really means whatever the
programmer wants it to mean", to which Andy Koenig responded
quite simply "yes", and another poster (Jim Adcock?) coined the
name of "Humpty-Dumpty const" (read Lewis Carrol's _Through_
_the_ _Looking_ _Glass_, if you don't get the reference).
Today, however, and for quite some time now, the consensus seems
to be logical const. In the case in question, if the
OtherObject is considered logically part of the state of
HasOther, then const functions of HasOther should not modify it.
(And if the name Has... means anything, it is.) Thus, for
example, most string classes will have a char* somewhere,
pointing to where the actual text resides; one expects const
functions of the class not to modify the actual text, however.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 26 '07 #18

P: n/a
James Kanze wrote:
On Sep 26, 11:04 am, Erik Wikström <Erik-wikst...@telia.comwrote:
>On 2007-09-26 06:32, Kira Yamato wrote:
No, one again you confuse what the state of the object is. The state of
the HasOther object is that it knows of another object of type
OtherObject. Changing the state of the OtherObject does not affect the
state of the HasOther object, just the state of OtherObject.

It depends. A long time ago (around 15 years), there were great
debates over logical const vs. bitwise const: I once said
something along the lines of "so const really means whatever the
programmer wants it to mean", to which Andy Koenig responded
quite simply "yes", and another poster (Jim Adcock?) coined the
name of "Humpty-Dumpty const" (read Lewis Carrol's _Through_
_the_ _Looking_ _Glass_, if you don't get the reference).
Today, however, and for quite some time now, the consensus seems
to be logical const. In the case in question, if the
OtherObject is considered logically part of the state of
HasOther, then const functions of HasOther should not modify it.
(And if the name Has... means anything, it is.) Thus, for
example, most string classes will have a char* somewhere,
pointing to where the actual text resides; one expects const
functions of the class not to modify the actual text, however.
This is indeed a sensible (probably *the* sensible) way of using const. However,
as the OP has found out, the language does not /require/ you to use const in
this way.

There are a number of good reasons for this: pointers and references are used
for both has-a relationships (a car has an engine, which is part of the car) and
is-related-to relationships (a car is related to its owner, but the owner is not
part of the car), so some pointers and references will be fair game for const
methods while others will not. The language's job is not to specify how you
shall use its features.

It is possible to use "const" to mean many different things, especially with
gratuitous use of "mutable". However, James Kanze's description of "logical
const" is the least surprising one - among other things, it means you don't have
to know about a string class's internal structure to know that its const methods
won't modify its contents.

Just because a programming language feature can be used badly doesn't make the
feature bad.

--
Philip Potter pgp <atdoc.ic.ac.uk
Sep 26 '07 #19

P: n/a
Victor Bazarov wrote:
Here is another pitfall for you:

class HasOther {
OtherObject *ptr;
public:
HasOther(OtherObject *p) : ptr(new OtherObject) {}
void Gotcha(OtherObject const& value) const
{
if (ptr) *ptr = value;
}
};
Well, what about this:

class Foo {
public:
Foo* that;
int other;
Foo() : that(this), other(1) {}
void Gotcha() const { that->other = 2; }
};

const Foo foo;

foo.Gotcha();

There we have an object that's actually const (not merely accessed through a
const pointer) modifying its own state (not merely someone else's state),
without a const_cast or mutable qualifier in sight.

-- Ben
Sep 27 '07 #20

P: n/a
On 2007-09-27 02:15, Ben Rudiak-Gould wrote:
Victor Bazarov wrote:
>Here is another pitfall for you:

class HasOther {
OtherObject *ptr;
public:
HasOther(OtherObject *p) : ptr(new OtherObject) {}
void Gotcha(OtherObject const& value) const
{
if (ptr) *ptr = value;
}
};

Well, what about this:

class Foo {
public:
Foo* that;
int other;
Foo() : that(this), other(1) {}
void Gotcha() const { that->other = 2; }
};

const Foo foo;

foo.Gotcha();

There we have an object that's actually const (not merely accessed through a
const pointer) modifying its own state (not merely someone else's state),
without a const_cast or mutable qualifier in sight.
If that is what you want you could just as well have used const_cast
instead, to make it more obvious to the reader what you were doing. Or
use mutable.

C++ is a very powerful language where you can access memory directly,
and there is nothing that prevents you from modifying that memory
(unless it is mapped in read only by the OS), so there is always a way
to get around whatever security the language provides.

"In C++ it's harder to shoot yourself in the foot, but when you do, you
blow off your whole leg."
— Bjarne Stroustrup.

--
Erik Wikström
Sep 27 '07 #21

P: n/a
On 2007-09-27 04:27:34 -0400, Erik Wikström <Er***********@telia.comsaid:
On 2007-09-27 02:15, Ben Rudiak-Gould wrote:
>Victor Bazarov wrote:
>>Here is another pitfall for you:

class HasOther {
OtherObject *ptr;
public:
HasOther(OtherObject *p) : ptr(new OtherObject) {}
void Gotcha(OtherObject const& value) const
{
if (ptr) *ptr = value;
}
};

Well, what about this:

class Foo {
public:
Foo* that;
int other;
Foo() : that(this), other(1) {}
void Gotcha() const { that->other = 2; }
};

const Foo foo;

foo.Gotcha();

There we have an object that's actually const (not merely accessed through a
const pointer) modifying its own state (not merely someone else's state),
without a const_cast or mutable qualifier in sight.

If that is what you want you could just as well have used const_cast
instead, to make it more obvious to the reader what you were doing. Or
use mutable.

C++ is a very powerful language where you can access memory directly,
and there is nothing that prevents you from modifying that memory
(unless it is mapped in read only by the OS), so there is always a way
to get around whatever security the language provides.
Yes, it is because of this possible abuse that it is incorrect to
assume that 'const' keeps an object's state constant. In the example
above, it does not even do bitwise-const, much less logical-const.

This is the pitfall.

As someone has pointed out before, it is not 'const' that keeps
object's state constant, but rather, it is the programmers who write
correct codes that keep the object's state constant.

--

-kira

Sep 27 '07 #22

P: n/a
On Sep 27, 2:15 am, Ben Rudiak-Gould <br276delet...@cam.ac.ukwrote:
Victor Bazarov wrote:
Here is another pitfall for you:
class HasOther {
OtherObject *ptr;
public:
HasOther(OtherObject *p) : ptr(new OtherObject) {}
void Gotcha(OtherObject const& value) const
{
if (ptr) *ptr = value;
}
};
Well, what about this:
class Foo {
public:
Foo* that;
int other;
Foo() : that(this), other(1) {}
void Gotcha() const { that->other = 2; }
};
const Foo foo;
foo.Gotcha();
There we have an object that's actually const (not merely
accessed through a const pointer) modifying its own state (not
merely someone else's state), without a const_cast or mutable
qualifier in sight.
That's undefined behavior. On the other hand, if int were
declared mutable, there'd be no problem.

More generally, the one place const does cause confusion is the
fact that it only inhibits changes through the particular lvalue
that is declared const; it doesn't guarantee in any way that the
object will not change state. For example:

Foo globalFoo ;

void
f( Foo const& foo )
{
std::cout << foo.state() << std::endl ;
globalFoo.changeState() ;
std::cout << foo.state() << std::endl ;
}

may output two different things if f is called with globalFoo as
an argument.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 27 '07 #23

P: n/a
On Sep 27, 10:27 am, Erik Wikström <Erik-wikst...@telia.comwrote:
C++ is a very powerful language where you can access memory
directly, and there is nothing that prevents you from
modifying that memory (unless it is mapped in read only by the
OS), so there is always a way to get around whatever security
the language provides.
If an object itself is defined const, the compiler is allowed to
put it into read-only memory (unless it contains a mutable
member). Modifying, or attempting to modify, a const object, is
undefined behavior.
"In C++ it's harder to shoot yourself in the foot, but when
you do, you blow off your whole leg."
? Bjarne Stroustrup.
Now that's more relevant to the spaghetti code thread, where C++
not only provides goto, but you have the possibility of
spaghetti inheritance and spaghetti templates as well.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Sep 27 '07 #24

This discussion thread is closed

Replies have been disabled for this discussion.