Is it possible to change a const variable without using pointers, subscripts, unions, or casts?
Printable View
Is it possible to change a const variable without using pointers, subscripts, unions, or casts?
Well . . . you could declare it mutable. ;)
Or you could print the address to the screen and demand that the user enters the exact address again, and modify that. :rolleyes:
Or you could edit the source code. That's changing the variable, isn't it? ;)
Or you could be very sneaky and unportable . . . .
Okay, that was really bad, and it probably wouldn't work anyway. Certainly not reliably.Code:int *p, x;
const int c = 3;
p = &x + 1;
*p = 4;
// now c is 4!
I thought mutable only lets const functions change a member variable?
AFAIK, changing a const variable results in undefined behavior and can only be done with unions, pointer arithmetic, const_cast, or placement new.
Mutable just means a member of a class/struct will never be const:
Code:struct MyStruct
{
int a; // Const-ness of 'a' depends on instantion
mutable int b; // 'b' is never const (even if instance is const)
const int c; // 'c' is always const (even if instance isn't const)
};
Mutable is the only option that doesn't involve pointers or casts.
Rudyman, you are correct except that in your example b is a part of MyStruct, and therefore a change to b is a change to MyStruct. Thus though the use of mutable the state of a const variable can be changed.
If you really need to change it, perhaps you should rethink the "const".
Your thread title is a dead giveaway.
There is a const_cast in C++ that defines a defined way of removing const. It should only be used as last retort.
As Salem says, if you need to modify const, then you should look back at the problem again and think hard, and really see if you really need to change the const.
Perhaps you should post your little problem so others can see if it's necessary or find a better solution?
The easiest way is to remove the const keyword and recompile ;)
Another way, if you're willing to lock yourself into a specific compiler and system (ie sacrifice all portability) is to use the asm keyword to introduce a suitable assembler construct to do what you want.
The compiler assumes that a constant doesn't change. If you use any dirty tricks to break that assumption (pointer casts, const casts, assembly), you'll just get miscompiled code and extremely elusive bugs.
The question betrays a very fundamental misconception about something.
Please, don't assume the reason I ask. This was a challenged posed in a C++ book.
In which case I would say that the answer is probably a simple "no".
(This is to examplify the problem - I'm not sure the syntax is actually valid!):
But we are no[color="Red"w[/color] breaking some of the good coding standards that we should all follow. (And it's using "pointers in disguise" under the name of references).Code:// file1.c
class A
{
public:
const int x = 7;
...
};
extern void func(A &a);
int main()
{
A a;
func(a);
}
//file2.c:
class A
{
public:
int x = 7; // Not missing const!
...
};
void func(A &a)
{
a->x++;
}
Edit: in red above
--
Mats
> This was a challenged posed in a C++ book.
Which book (noting that there are in fact a lot of crap books on C++, and precious few good ones).
The misconception could be on part of the book. ;) Please give us the name of the book and the context of the question - most likely we'll have to warn people away from it now.
matsp: That's a violation of the ODR. No diagnostic required, but the program has undefined behaviour, like any other program that attempts to change a const variable.
ODR = "One Declaration Rule"? Yes, I agree that it's essentially using a union in disguise, and it's definitely "bad coding standards" anyways. I'm just trying to find some way that would actually achieve this.
And yes, I agree that I wouldn't expect the compiler to come up with a x that is different from 7 if we added code to output x after the call to func - as far as the compiler is concerned, it does not expect x to be anything different from 7 - so it can replace all places where x is used with the number 7 as a constant. Job done. The func code would then access 4 bytes that isn't actually x (it may be some other member variable or some random data beyond the size of the variable, for example). That is not what the programmer who wrote such a thing would expect.
--
Mats
"One Definition Rule". You may have multiple declarations, but only one definition per translation unit. Furthermore, there may be only one definition of a non-inline, non-template function across all translation units. Finally, if there are multiple definitions of anything else across translation units (e.g. a class definition in a header), they must all be identical on the token level.