In the evening, you have no intention to go over to the Section 94th Constants on the 'The C ++ programming language special version' (English version) of Bjarne stroustrup, the original Article 'C ++ offers the concept of a user-defined constant, a const, to express the notion that a value doesn' t change directly. 'The word is directly. Since it cannot be directly change, I will try indirectly change.
The problem is found in the indirectly change. The Code is as follows:
# Include <iostream>
Int main (){
Const int A = 2007; // This is a constant, and we cannot directly change '^_^
Int * P = const_cast <int *> (& A); // use hijack.
* P = 2008; // tampered
STD: cout <"A =" <A <STD: Endl; // expected output 2008
STD: cout <"* P =" <* P <STD: Endl;
STD: cout <"& A =" <& A <STD: Endl;
STD: cout <"P =" <p <STD: Endl;
Return 0;
}
First, I used the G ++ compilation of mingw on windows. I was shocked by the output:
A = 2007
* P = 2008
& A = 0x23ff74
P = 0x23ff74
I thought a should be hijack, and the result a is still intact. The key is that the address of a printed in the last two rows and the point of P are both in one place, is C ++ so intelligent and protective against constants. No. Try another platform. I moved the source code to Solaris, which is also a G ++ compiler with the same output results.
After thinking about it, continue to look down at this section. Suddenly found this sentence: 'If the compiler knows every use of the const, it need not allocate space to hold it. '... 'The Common simple and common case is the one in which the value of the constant is known at compile time and no storage needs to be allocated. ', Zuo Si thought again, so in some cases, a is treated as a macro-like method, such as: STD :: cout <"A =" <A <STD: Endl; here, cout outputs a constant expression. The Compiler estimates that A is replaced with 2007 directly, which is equivalent to STD :: cout <"A =" <2007 <STD: Endl; then int * P = const_cast <int *> (& A); in this case, you need to assign an address for. Some people say that the output operation of A is after the address is allocated. Why does it still output 2007? Let's look at it from the compiler's perspective, when the compiler parses const int A = 2007, it finds that this is a constant and records it in the constant symbol table first, and then parses const_cast <int *> (&) allocate memory for a on the stack, but the constant symbol table is referenced first when the block A is output. In the output & A, the address is used, therefore, the stack address previously allocated is assigned here.
Let's look at another example:
# Include <iostream>
Int main (){
Int I = 2006;
Const int A = I + 1;
Int * P = const_cast <int *> (& );
* P = 2008; // tampered
STD: cout <"A =" <A <STD: Endl; // expected output 2008
STD: cout <"* P =" <* P <STD: Endl;
STD: cout <"& A =" <& A <STD: Endl;
STD: cout <"P =" <p <STD: Endl;
Return 0;
}
In this example, const int A = I + 1; use a constant expression to assign an initial value to constant A. According to Bjarne stroustrup, it is necessary to allocate memory to. In this case, I think the compiler may not leave a position in the constant symbol table. In the print output of A below, A is actually hijack.
Output result:
A = 2008
* P = 2008
& A = 0x23ff70
P = 0x23ff70
Let's look at another example:
# Include <iostream>
Int main (){
Const int I = 2006;
Const int A = I + 1;
Int * P = const_cast <int *> (& );
* P = 2008; // tampered
STD: cout <"A =" <A <STD: Endl; // expected output 2008
STD: cout <"* P =" <* P <STD: Endl;
STD: cout <"& A =" <& A <STD: Endl;
STD: cout <"P =" <p <STD: Endl;
Return 0;
}
When parsing to const int I = 2006, the compiler first saves I as a constant to the constant symbol table. When const int A = I + 1 is actually equivalent to const int A = 2006 + 1, when the compiler is optimized, the compiler directly obtains a = 2007 and is a constant and is saved to the constant table. The following process is the same as the first example.