Reputation: 4925
By using the const
qualifier a variable is supposed to be made read-only. As an example, an int
marked const
cannot be assigned to:
const int number = 5; //fine to initialize
number = 3; //error, number is const
At first glance it looks like this makes it impossible to modify the contents of number
. Unfortunately, actually it can be done. As an example const_cast
could be used (*const_cast<int*>(&number) = 3
). This is undefined behavior, but this doesn't guarantee that number
does not actually get modified. It could cause the program to crash, but it could also simply modify the value and continue.
Is it possible to make it actualy impossible to modify a variable?
A possible need for this might be security concerns. It might need to be of highest importance that some very valuable data must not be changed or that a piece of data being sent must not be modified.
Upvotes: 4
Views: 800
Reputation: 131636
const
is not intended to make a variable read-only.The meaning of const x
is basically:
Hey compiler, please prevent me from casually writing code in this scope which changes
x
.
That's very different from:
Hey compiler, please prevent any changes to
x
in this scope.
Even if you don't write any const_cast
's yourself - the compiler will still not assume that const
'ed entities won't change. Specifically, if you use the function
int foo(const int* x);
the compiler cannot assume that foo()
doesn't change the memory pointed to by x
.
Variables vary... so, naturally, a way to prevent that is using values which aren't stored in variables. You can achieve that by using...
enum : int { number = 1 }
.#define NUMBER 1
<- Not recommendedinline int get_number() { return 1; }
As @SebastianHoffman suggests, typical platforms allow marking some of a process' virtual memory space as read-only, so that attempts to change it result in an access violation signal to the process and the suspension of its execution. This is not a solution within the language itself, but it is often useful. Example: When you use string literals, e.g.:
const char* my_str = "Hello world";
const_cast<char*>(my_str)[0] = 'Y';
Your process will likely fail, with a message such as:
Segmentation fault (core dumped)
Upvotes: 2
Reputation: 1062
While most of the answers in this thread are correct, but they are related to const
, while the OP is asking for a way to have a constant value defined and used in the source code. My crystal ball says that OP is looking for symbolic constants (preprocessor #define statements).
#define NUMBER 3
//... some other code
std::cout<<NUMBER;
This way, the developer is able to parametrize values and maintain them easily, while there's virtually no (easy) way to alter it once the program is compiled and launched.
Just keep in mind that const variables are visible to debuggers, while symbolic constants are not, but they require no additional memory. Another criteria is the type checking, which is absent in case of symbolic constants, as well as for macros.
Upvotes: 2
Reputation: 122516
There is no way to specify what code does that does not adhere to the specification.
In your example number
is truly constant. You correctly note that modifiying it after a const_cast
would be undefined beahvior. And indeed it is impossible to modify it in a correct program.
Upvotes: 1
Reputation: 8220
If you know the program at compile-time, you can place the data in read-only memory. Sure, someone could get around this, but security is about layers rather than absolutes. This makes it harder. C++ has no concept of this, so you'll have to inspect the resulting binary to see if it's happened (this could be scripted as a post-build check).
If you don't have the value at compile-time, your program depends on being able to change / set it at runtime, so you fundamentally cannot stop that from happening.
Of course, you can make it harder though things like const
so the code is compiled assuming it won't change / programmers have a harder time accidentally changing it.
You may also find constexpr
an interesting tool to explore here.
Upvotes: 1
Reputation: 2914
No, this is not the concern of a programming language. Any "access" protection is only superficial and only exists at compile-time.
Memory of a computer can always be modified at runtime if you have the corresponding rights. Your OS might provide you with facilities to secure pages of memory though, e.g VirtualProtect() under Windows.
(Notice that an "attacker" could use the same facilities to restore the access if he has the privilege to do so)
Also I assume that there might be hardware solutions for this.
There is also the option of encrypting the data in question. Yet it appears to be a chicken-and-egg situation as the private key for the encryption and decryption has to be stored somewhere in memory as well (with a software-only solution).
Upvotes: 3