 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Le Chaud Lapin Guest
|
Posted: Fri Apr 23, 2004 4:04 pm Post subject: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
Hallo All,
I have a List<> template that has an index, capacity, and population.
Before I was using member functions to get the value each of these
three data members, adding underbars to end of data member name so
that function name would not clash with the data member name.
Ideally, there should be a method of specifying a pseudo-read-only
attribute for the data members, so that I can simply use the .
operator to get to their values:
List<String> hit_list;
if (hit_list.population > 0)
// go get my water gun
But with no read-only attribute, this is error prone:
if (hit_list.population = 13) // ooops..I meant to write ==
// bad luck if is squirt my enemies
Lately I started using const to make the data members "read-only":
template <typename Element> class List
{
// ...
public :
const unsigned int index;
const unsigned int capacity;
const unsigned int population;
} ;
Whenever I need to actually update a data member within a member
function, I turn off the "const ness":
++const_cast<unsigned int &>(population);
This requires introduction of only one name, is at least as fast as
in-lining, and also elimates the subtle error of testing whether a
pointer to a function is non-zero when was was intended was to test
the value returned by the function:
if (hit_list.population) // ooops....missing ()
// go get my water gun
Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
-Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
llewelly Guest
|
Posted: Sat Apr 24, 2004 12:47 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
[email]unoriginal_username (AT) yahoo (DOT) com[/email] (Le Chaud Lapin) writes:
| Quote: | Hallo All,
I have a List<> template that has an index, capacity, and population.
Before I was using member functions to get the value each of these
three data members, adding underbars to end of data member name so
that function name would not clash with the data member name.
Ideally, there should be a method of specifying a pseudo-read-only
attribute for the data members, so that I can simply use the .
operator to get to their values:
List<String> hit_list;
if (hit_list.population > 0)
// go get my water gun
But with no read-only attribute, this is error prone:
if (hit_list.population = 13) // ooops..I meant to write ==
// bad luck if is squirt my enemies
Lately I started using const to make the data members "read-only":
template <typename Element> class List
{
// ...
public :
const unsigned int index;
const unsigned int capacity;
const unsigned int population;
} ;
Whenever I need to actually update a data member within a member
function, I turn off the "const ness":
++const_cast<unsigned int &>(population);
This requires introduction of only one name, is at least as fast as
in-lining, and also elimates the subtle error of testing whether a
pointer to a function is non-zero when was was intended was to test
the value returned by the function:
if (hit_list.population) // ooops....missing ()
// go get my water gun
Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
|
It may not work with your co-worker's brain. Now that your code is
all cluttered with const_cast<>s, he starts assuming const_cast<>
is ok. And when a bug appears, he doesn't re-think the
const_cast<>; he just assumes its ok. If the bug is in the
const_cast<>, he starts thinking the compiler is generating bad
code for operator++, and he wastes 3 hours staring at generated
assembly. Finally he goes to you for help. But you wrote the
const_cast<>, so you think, 'it can't be wrong. I've got tons of
experience writing const_cast<>s.' So you can't find the bug
either.
Don't tell me that can't happen; you're invoking undefined
behavior. ANYTHING can happen. :-)
How about this:
class foo
{
unsigned int index;
public:
const unsigned int& read_index;
foo():index(0),read_index(index){}
/* ... */
};
Of course that probably has memory and performance overhead in
practice.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Sat Apr 24, 2004 12:48 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
Le Chaud Lapin wrote:
| Quote: | Lately I started using const to make the data members "read-only":
template <typename Element> class List
{
// ...
public :
const unsigned int index;
const unsigned int capacity;
const unsigned int population;
} ;
Whenever I need to actually update a data member within a member
function, I turn off the "const ness":
++const_cast<unsigned int &>(population);
|
7.1.5.1/4 looks pretty clear to me:
"Except that any class member declared mutable (7.1.1) can be modified,
any attempt to modify a const object during its lifetime (3. results
in undefined behavior."
| Quote: |
This requires introduction of only one name, is at least as fast as
in-lining, and also elimates the subtle error of testing whether a
pointer to a function is non-zero when was was intended was to test
the value returned by the function:
if (hit_list.population) // ooops....missing ()
// go get my water gun
??? Don't understand that! This should never compile IMO. |
If 'population' is a member function, this test looks pointless to me,
furthermore this syntax won't compile anyway.
If 'population' is a pointer to member function, the correct calling
syntax would be
if( hitlist.*population)() )
while the correct testing syntax is
if(population)
or (nicer IMO)
if(population != 0)
| Quote: |
Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
You promised not to modify 'population' during the lifetime of your object. |
A well optimizing compiler could take advantage of 7.1.5.1/4 to keep
sometimes a copy of 'population' in a register (if one is available) rather
than reloading it after each member function call, so your modifications
through const_cast would (at least sometimes) not be taken into account.
Falk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Jeff Schwab Guest
|
Posted: Sat Apr 24, 2004 11:16 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
Le Chaud Lapin wrote:
| Quote: | Whenever I need to actually update a data member within a member
function, I turn off the "const ness":
++const_cast<unsigned int &>(population);
This requires introduction of only one name, is at least as fast as
in-lining, and also elimates the subtle error of testing whether a
pointer to a function is non-zero when was was intended was to test
the value returned by the function:
if (hit_list.population) // ooops....missing ()
// go get my water gun
Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
|
Modifying a const object through a const_cast invokes undefined behavior
(7.1.5.1). It's not guaranteed to do what you think it's doing.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Alexei Polkhanov Guest
|
Posted: Sun Apr 25, 2004 1:49 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
You trying to use language features to avoid most frequent typos. You
might succeed in "killing" this one, I mean "if ( = )" but what about
others ? Some compilers will let you to set flags to prohibit assignment
inside if or at least will warn you, well gcc does give a warning and
they do it consistently for many common "typo-prone" situations.
I use whatever compiler offers me first, then I do myself or ask couple
of intern students to go through source code with CHECKLIST. So if you
make so many assignment on if error just put it into checklist.
Methodology described in details in “Code Complete”.
Trying to play with language feutures in this situation does not help
and even make things worth because you WRITE THE CODE FOR THOSE WHO
WILL READ IT, and you take care about readers first - everything else
after that. making code harder to read and understand for sake of
avoiding typos IMHO IS UNACCEPTABLE.
Alexei.
Jeff Schwab wrote:
| Quote: | Le Chaud Lapin wrote:
Whenever I need to actually update a data member within a member
function, I turn off the "const ness":
++const_cast<unsigned int &>(population);
This requires introduction of only one name, is at least as fast as
in-lining, and also elimates the subtle error of testing whether a
pointer to a function is non-zero when was was intended was to test
the value returned by the function:
if (hit_list.population) // ooops....missing ()
// go get my water gun
Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
Modifying a const object through a const_cast invokes undefined behavior
(7.1.5.1). It's not guaranteed to do what you think it's doing.
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Le Chaud Lapin Guest
|
Posted: Sun Apr 25, 2004 2:04 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
Falk Tannhäuser <falk.tannhauser (AT) crf (DOT) canon.fr> wrote
| Quote: | Le Chaud Lapin wrote:
7.1.5.1/4 looks pretty clear to me:
"Except that any class member declared mutable (7.1.1) can be modified,
any attempt to modify a const object during its lifetime (3. results
in undefined behavior."
if (hit_list.population) // ooops....missing ()
// go get my water gun
??? Don't understand that! This should never compile IMO.
If 'population' is a member function, this test looks pointless to me,
furthermore this syntax won't compile anyway.
If 'population' is a pointer to member function, the correct calling
syntax would be
if( hitlist.*population)() )
while the correct testing syntax is
if(population)
or (nicer IMO)
if(population != 0)
|
Yes, that's right. I think I encountered this situation inside of a
member function where population was used, which is what I meant to
illustrate.
| Quote: | Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
You promised not to modify 'population' during the lifetime of your object.
A well optimizing compiler could take advantage of 7.1.5.1/4 to keep
sometimes a copy of 'population' in a register (if one is available) rather
than reloading it after each member function call, so your modifications
through const_cast would (at least sometimes) not be taken into account.
|
I think I already know the answer, but I will ask anyway:
Can I not rely on const_cast<..&>(_) to force a reference to the
actual data member? I know the standard does not prescribe this
behavior, but there are many things the standard does not prescribe
but can be inferred without getting bitten.
I also know shaky inferences are bad bad bad, but a little wishful
thinking cannot hurt. :D
-Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Le Chaud Lapin Guest
|
Posted: Sun Apr 25, 2004 2:05 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
llewelly <llewelly.at (AT) xmission (DOT) dot.com> wrote
| Quote: | unoriginal_username (AT) yahoo (DOT) com (Le Chaud Lapin) writes:
Ideally, there should be a method of specifying a pseudo-read-only
attribute for the data members, so that I can simply use the .
operator to get to their values:
[snipped]
Lately I started using const to make the data members "read-only":
[snipped]
Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
It may not work with your co-worker's brain. Now that your code is
all cluttered with const_cast<>s, he starts assuming const_cast
is ok. And when a bug appears, he doesn't re-think the
const_cast<>; he just assumes its ok. If the bug is in the
const_cast<>, he starts thinking the compiler is generating bad
code for operator++, and he wastes 3 hours staring at generated
assembly. Finally he goes to you for help. But you wrote the
const_cast<>, so you think, 'it can't be wrong. I've got tons of
experience writing const_cast<>s.' So you can't find the bug
either.
|
LOL.
| Quote: | How about this:
class foo
{
unsigned int index;
public:
const unsigned int& read_index;
foo():index(0),read_index(index){}
/* ... */
};
|
Interesting, but yes, pointer overhead is a little too much.
Might have to (grudgingly) put the member functions back.
-Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Old Wolf Guest
|
Posted: Mon Apr 26, 2004 8:25 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
[email]unoriginal_username (AT) yahoo (DOT) com[/email] (Le Chaud Lapin) wrote:
| Quote: | llewelly <llewelly.at (AT) xmission (DOT) dot.com> wrote:
[email]unoriginal_username (AT) yahoo (DOT) com[/email] (Le Chaud Lapin) writes:
Ideally, there should be a method of specifying a pseudo-read-only
attribute for the data members, so that I can simply use the .
operator to get to their values:
How about this:
class foo
{
unsigned int index;
public:
const unsigned int& read_index;
foo():index(0),read_index(index){}
/* ... */
};
Interesting, but yes, pointer overhead is a little too much.
Might have to (grudgingly) put the member functions back.
|
There are no pointers in this code. References do not have an overhead.
They are resolved at compile-time. The size and speed of your compiled
program will be identical with or without this reference.
Here is another possible nomenclature, if you do want index
to be writable without a member function, and aren't pedantic:
public:
int write_index;
const int &index;
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Matthew Hall Guest
|
Posted: Mon Apr 26, 2004 8:26 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
Le Chaud Lapin wrote:
| Quote: | Falk Tannh=E4user <falk.tannhauser (AT) crf (DOT) canon.fr> wrote
Le Chaud Lapin wrote:
Anyone know of any (obvious or non-obvious) reasons why this will not
work consistently accross all compilers?
You promised not to modify 'population' during the lifetime of your ob=
ject.
A well optimizing compiler could take advantage of 7.1.5.1/4 to keep
sometimes a copy of 'population' in a register (if one is available) r=
ather
than reloading it after each member function call, so your modificatio=
ns
through const_cast would (at least sometimes) not be taken into accoun=
t. |
| Quote: | I think I already know the answer, but I will ask anyway:
Can I not rely on const_cast<..&>(_) to force a reference to the
actual data member? I know the standard does not prescribe this
behavior, but there are many things the standard does not prescribe
but can be inferred without getting bitten.
I also know shaky inferences are bad bad bad, but a little wishful
thinking cannot hurt. :D
|
The problem is not just a matter of optimization, but that the compiler
may put the 'data member' you refer to in a place not writable by you.
Not even just 'you', but not writable to your program at all (in program
memory, or the like.) On embedded systems, it could place the constant
in actual ROM. In fact, I believe it is possible for the compiler to not
use any storage at all in some cases:
const int konstant=7;
....
a+=konstant;
....
b+=konstant;
Here, the compiler might choose to use an 'add immediate' instruction,
availible on many architectures, to place the bits representing 7
directly into a machine instruction, rather than using an indirect
lookup. Even if the architecture allowed self modifying code, the
example above shows that the 'add immediate' instructions might be
scattered across the the code, so that modifying 'konstant' would
require updating the machine code at many different locations in program
memory, perhaps across translation units. Which would require linker
support for this construct. Which is beginning to enter the realm of the
absurd, in my very humble opinion.
So the point is that you can't rely on const_cast<...&> to force a
reference to the 'actual data member' and write to it, since for a
member originally declared as const:
A) The memory might be write protected,
B) The memory might be physically unwritable, as in ROM, and
C) The actual data member need not even exist in a single location in
memory.
Your inference relies on the fact that const_cast<...&> will return a
reference to a (writable) location in memory. When you declare anything
const, you can't rely on that anymore.
-matt
BTW - In my last example, I realize that by taking the address of
'konstant', which is done implicitly by the const_cast<...&>, the
compiler is required to find some storage for 'konstant'. However, the
compiler is (to the best of my knowledge) still allowed to issue the
'add immediate' instructions as above, so that the constant now exists
in multiple locations.
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
John Potter Guest
|
Posted: Mon Apr 26, 2004 10:25 pm Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
On 26 Apr 2004 04:26:56 -0400, Matthew Hall <mahall (AT) math (DOT) uiuc.edu>
wrote:
| Quote: | The problem is not just a matter of optimization, but that the compiler
may put the 'data member' you refer to in a place not writable by you.
Not even just 'you', but not writable to your program at all (in program
memory, or the like.) On embedded systems, it could place the constant
in actual ROM. In fact, I believe it is possible for the compiler to not
use any storage at all in some cases:
|
There is little sense in trying to make logic out of law. This thread
is about a const member of a non-const object. The member is
initialized at runtime and has an unknown value at compile time.
Claiming that it might be in an immediate instruction is nonsense. The
standard says that using const_cast to modify the member is undefined
behavior. We all know that it will almost certainly do exactly what we
want on all real implementations. The only question is whether we want
to depend on undefined behavior.
John
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Le Chaud Lapin Guest
|
Posted: Tue Apr 27, 2004 10:41 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
[email]oldwolf (AT) inspire (DOT) net.nz[/email] (Old Wolf) wrote in message news:<843a4f78.0404252144.47262ebc (AT) posting (DOT) google.com>...
| Quote: | unoriginal_username (AT) yahoo (DOT) com (Le Chaud Lapin) wrote:
llewelly <llewelly.at (AT) xmission (DOT) dot.com> wrote:
How about this:
class foo
{
unsigned int index;
public:
const unsigned int& read_index;
foo():index(0),read_index(index){}
/* ... */
};
Interesting, but yes, pointer overhead is a little too much.
There are no pointers in this code. References do not have an overhead.
They are resolved at compile-time. The size and speed of your compiled
program will be identical with or without this reference.
|
Hi Wolf,
I think in this case there is. Since, for this particular type of
example, there must be a 1-to-1 correlation between the reference and
the thing it refers to, and the reference can take on arbitrary
parameters at run-time, if you do sizeof(foo), you're bound to get
some value that includes the size of the pointer implementing the
reference.
-Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze@gabi-soft.fr Guest
|
Posted: Tue Apr 27, 2004 6:08 pm Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
John Potter <jpotter (AT) falcon (DOT) lhup.edu> wrote
| Quote: | The only question is whether we want
to depend on undefined behavior.
|
A perhaps just as important question is whether we want to confuse the
reader. I don't know about others here, but when I see a data field in
a class declared const, I tend to suppose that its value won't change
during the lifetime of the object. Anything that does change it will
*really* confuse me.
--
James Kanze GABI Software mailto:kanze (AT) gabi-soft (DOT) fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Le Chaud Lapin Guest
|
Posted: Wed Apr 28, 2004 12:36 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
Matthew Hall <mahall (AT) math (DOT) uiuc.edu> wrote
[snip]
| Quote: | Le Chaud Lapin wrote:
Can I not rely on const_cast<..&>(_) to force a reference to the
actual data member? I know the standard does not prescribe this
behavior, but there are many things the standard does not prescribe
but can be inferred without getting bitten.
[snip]
The problem is not just a matter of optimization, but that the compiler
may put the 'data member' you refer to in a place not writable by you.
|
First, here is the code again:
template <typename Element> class List
{
/...
public :
const unsigned int population; // 'data member'
void f ()
{
const_cast<unsigned int &>(population)++;
}
} ;
I was wondering if I could assume that the compiler would put
'population' in writable a location for the following reasons:
1. I have an object that is inherently non-const.
2. The scalar data member is the only thing that was declared const.
3. The remainder of the object, being non-const, must be mutable
4. I am initializing the const memeber at run-time.
5. Mapping between distinct objects and distinct const members is
1-to-1
4. The compiler does not know if I will have 1 or 1,000,000 objects
Because of point #4, it would be very wild indeed if the compiler made
1,000,000 separate scalar spaces for 1,000,000 objects just for that
one const data member. Furthermore, since the amount of requistite
space for the objects would be indeterminate, there would be some code
overhead to manage access to the separate members. Since it is likely
that I would want to copy the object,the compiler would again need
special code to go fetch the const member from the special locations.
And also, if I wanted to take the address of the data member for a
particular object, potentially for a dereference-then-read sequence,
on the stack or the heap, the compiler and memory libraries would have
have special code to account for the fact that the data member is not
actually contiguous with the rest of the object. The same thing would
be true for an abitrary pointer to an object. If I used the *. or ->
operators on the pointer to get to the const data member, extra code
would have to be executed to (1) go and see if the pointer to the
object is valid (2), find the const data memeber for reading.
It is possible on some architectures to define read-only segments as
small as 1 byte, but again, special code would have to exist in both
the compiler supplied stack allocation code, as well as the heap code
for ::operator new().
I know these points are not strong enough to provide a guarantee, but
it does seem to get me out of the bushes, or does it?
-Chaud Lapin-
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
llewelly Guest
|
Posted: Wed Apr 28, 2004 12:38 am Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
[email]oldwolf (AT) inspire (DOT) net.nz[/email] (Old Wolf) writes:
| Quote: | unoriginal_username (AT) yahoo (DOT) com (Le Chaud Lapin) wrote:
llewelly <llewelly.at (AT) xmission (DOT) dot.com> wrote:
[email]unoriginal_username (AT) yahoo (DOT) com[/email] (Le Chaud Lapin) writes:
Ideally, there should be a method of specifying a pseudo-read-only
attribute for the data members, so that I can simply use the .
operator to get to their values:
How about this:
class foo
{
unsigned int index;
public:
const unsigned int& read_index;
foo():index(0),read_index(index){}
/* ... */
};
Interesting, but yes, pointer overhead is a little too much.
Might have to (grudgingly) put the member functions back.
There are no pointers in this code. References do not have an
overhead.
[snip] |
Run this little program:
#include<iostream>
#include<ostream>
class foo
{
unsigned int index;
public:
const unsigned int& read_index;
foo():index(0),read_index(index){}
};
class bar
{
unsigned int index;
public:
bar():index(0){}
};
int main()
{
std::cout << "sizeof(foo) " << sizeof(foo) << std::endl;
std::cout << "sizeof(bar) " << sizeof(bar) << std::endl;
}
And post its output for the implementation you use. For gcc 3.4, on
i686-freebsd5.2, it prints:
sizeof(foo) 8
sizeof(bar) 4
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Falk Tannhäuser Guest
|
Posted: Wed Apr 28, 2004 7:24 pm Post subject: Re: Using const + const_cast<>() To Obviate ::set(), get() |
|
|
Le Chaud Lapin wrote:
| Quote: |
template <typename Element> class List
{
/...
public :
const unsigned int population; // 'data member'
void f ()
{
const_cast<unsigned int &>(population)++;
}
} ;
I was wondering if I could assume that the compiler would put
'population' in writable a location for the following reasons:
|
The problem is not only whether or not 'population' is in
a writable location, but (as already stated in this thread)
with optimization.
Consider this program:
________________________________________________________________
#include <iostream>
#include <ostream>
struct List
{
unsigned const population;
List(unsigned p) : population(p) {}
void lie_to_my_compiler() { ++const_cast<unsigned&>(population); }
};
int main()
{
List li(42);
std::cout << li.population << ' ';
li.lie_to_my_compiler();
std::cout << li.population << 'n';
return 0;
}
________________________________________________________________
Because of 7.1.5.1/4, the compiler has the right to keep the
value of li.population read before the call of lie_to_my_compiler()
cached in a register for the second use, so this program could
very well print "42 42" instead of "42 43" as you would expect.
I tested with gcc 3.3.1 CygWin which doesn't implement this
optimization, but other compilers or newer versions could
very well do so (perhaps in function of optimization command
line switches). That's what "undefined behaviour" is about!
Does anybody know a compiler that optimizes in this case?
Furthermore, as others already said, this code will also surprise
the poor maintenance programmer who assumes that 'const' means
'const' means 'const'...
Falk
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|