Objective
A few days ago the woman ticket asked me a Ali's face question, is about the C + + language const constant, in fact, she mentioned that I know the point of inspection: it is certain that the const constant memory is not allocated in the Read-only storage area, the const constant memory allocation area is a very common stack or global zone. That is, the const constant is just a compiler check at compile time , there is no read-only area.
So the const constants and constant strings of C + + are different, and the constant strings are stored in the Read-only area, and their specific storage areas are different.
As if Yang Lixiang teacher in class to give the example (said things forget almost, but examples remember, what tore hukou, moon cake mold, etc.):
Scene: An old-fashioned movie projector, a ticket-inspector at the gate, a final row of the show Master on that seat, a lot of spectators.
Your movie ticket has your name, the ticket inspector's hand has a name and a table of the seat number, the ticket inspector does not allow the audience to sit in a position.
So the game began, every auditorium in the cinema is a const constant type, the ticket inspector is the compiler, in the audience when the door, everyone must sit on their own ticket seats, that is to say the audience must take their own ticket door. You won't be allowed to go in with someone else's ticket, so you can't change your seat.
Analogy to the C + + language, the scenario should be: for which Const constants, at compile time has been decided, they in memory location, if you directly change the value of this constant is not legal. It's like you can't take a movie ticket to the cinema, because the ticket clerk has a seat number to the name of the mapping table, he knows which seat to sit, and do not let the audience at random exchange (This example is really good image ah, Yang teacher said not so good, I later according to their understanding slightly exaggerated). In fact, the ticket inspector in the hand of the mapping table is the compiler's symbol table, is not really very image, about this symbol table behind said.
So the new question came, after the audience into the cinema, I told the next man, I give you 100 bucks, you give me a change of position, if he agreed, we can change. The ticket clerk is not in the way, enter all come in, still can how. That's why two of them switched seats.
The const constant of C + + is the same as when the compiler looks at the symbol table in its hand at compile time, and if you take a const constant and you want to modify the value of the constant, he rejects it. But this check value will happen in the compiler, if I can bypass the compiler, in the run time to modify the const value, it will be very easy to do, as I said before, I gave the man 100 pieces to take care of. So there is no difference between the storage space of the const constant and the storage space of the other variables, and its constant does not allow the check to occur only at the compiler's compilation stage.
But the constant string storage location is different, it's storage location is read-only area, like the last of the movie theater the location of the projector, there is a special position, is really not allowed to exchange, you give him 1000 not to you, because the master to show in that position, or can not see the film. Of course, it is also very simple to implement this read-only storage area, and it is good to mark the page property of that memory as read-only.
By the time, I thought of this:
Const int /* */intconst/**/constint Const /* */
What a long-winded example, in fact, very simple truth, is for fun, good to remember. Let's talk about the implementation mechanism of const constants, some concrete implementations are given below.
In fact, the problem of women votes is not difficult, is a C + + language, a knowledge point, in short, a constant folding.
Say a wrong understanding (why say a wrong understanding, because it helps to understand correctly, haha): Collapsible constants are like macros, and references to const constants in the pre-compilation phase are replaced with values corresponding to constants. is no different from normal macro substitution, and the compiler does not allocate storage space for that constant.
See clearly, the above is a wrong understanding, the constant folding will be like a macro substitution to replace a reference to a constant with a constant value, but the constant is allocated space, and by the compiler to check the constant property.
#define PI 3.14
int Main ()
{
Const int r = 10;
int p = PI; //Here in the pre-compilation phase to generate a macro substitution, pi directly replaced with 3.14, is actually int p = 3.14
int len = 2 * r; //There will be a constant folding, that is, the constant R reference will be replaced by its corresponding value, equivalent to int len = 2 *;
return 0;
}
As described in the code above, the effect on the constant folding surface is the same as the macro substitution, but the "effect is the same", and the real difference between the two is that the macro is a character constant, after the macro substitution is completed in the pre-compilation phase, the macro name disappears, all references to the macro such as Pi have been replaced by its corresponding There is certainly no need for the compiler to maintain this symbol. When a constant collapse occurs, a reference to a constant is replaced with the value of the constant, such as r, but the constant name R does not disappear, and the compiler places it in the symbol table , allocating space, stack space, or global space for the variable. Since it is placed in the symbol table, it means that the address of the variable can be found (burying a foreshadowing first).
In order to better reflect the constant folding, see the following comparison experiment:
intMain () {intI0 = One; Const inti =0;//Defining Constants I int*j = (int*) &i;//See here can take the value of I, Judge I must after their own memory space*j =1;//Modify the memory that J points toprintf"0x%p\n0x%p\n%d\n%d\n", &i,j,i,*j);//Watch the experimental results Const intCK =9;//This control experiment is to observe that the effect of a reference to a constant CK intIK =ck; intI1 =5;//This control experiment is to distinguish between constants and references to variables. intI2 =I1; return 0;}
Let's look at the output of different compilers
vc6.0:
VS2010:
Output from g++:
Note: For Linux, GCC in the gun is used to compile the C language compiler for. c files, and g++ is the C + + language compiler used to compile. cpp.
We are talking about C + + negotiation folding, so the source file if the. cpp can. (The const constant of C is the last word)
The results of the above program run at least two points:
(1) I and J address the same, point to the same piece of space, I though is a collapsible constant, but I do have their own space
(2) I and J point to the same piece of memory, but *J = 1 after the memory modification, according to reason, *j==1,i should also be equal to 1, and the experimental result is really I equals 0.
For what it is, this is what this article says, I is a collapsible constant, the reference to I in the compilation phase has not been replaced with the value of I, and different macro replace, the i is also stored in the symbol table.
Other words:
printf ("0x%p\n0x%p\n%d\n%d\n", &i,j,i,*j);
The I in the preprocessing phase has been replaced, in fact has been changed to:
printf ("0x%p\n0x%p\n%d\n%d\n", &i,j,0,*j);
I also have this variable in the symbol table, otherwise I take the address is not legal, this is the difference with the macro substitution.
In order to be more intuitive, the following directly on the program's anti-compilation assembly language:
(1) Method: Make a Breakpoint debugging window disassembly (there are many features, such as memory multithreading, etc.)
(2) Disassembly code:
1---d:\cv_projects\commontest\commontest\commontest.cpp------------------------2#include <stdio.h>3 intMain ()4 {5 01311380Push EBP6 01311381mov ebp,esp7 01311383Sub esp,114h8 01311389push EBX9 0131138A push ESITen 0131138B Push EDI One0131138C Lea edi,[ebp-114h] A 01311392mov ecx,45h - 01311397mov eax,0cccccccch - 0131139C Rep stos dword ptr Es:[edi] the intI0 = One; - 0131139E mov dword ptr [I0],0BH - - Const inti =0;//Defining Constants I +013113A5 mov dword ptr [i],0 //The compiler does allocate a stack space for the constant I and assigns a value of 0 - int*j = (int*) &i;//See here can take the value of I, Judge I must after their own memory space + 013113AC Lea Eax,[i] A 013113AF mov dword ptr [J],eax at*j =1;//Modify the memory that J points to - 013113b2 mov eax,dword ptr [j] -013113B5 mov dword ptr [EAX],1 -printf"0x%p\n0x%p\n%d\n%d\n", &i,j,i,*j);//Watch the experimental results - 013113BB mov esi,esp - 013113BD mov eax,dword ptr [j] in 013113c0 mov ecx,dword ptr [eax] - 013113c2 push ecx to013113C3 push0 + 013113C5 mov edx,dword ptr [j] - 013113c8 push edx the 013113c9 Lea Eax,[i] * 013113CC push eax $013113CD Push Offsetstring "0x%p\n0x%p\n%d\n%d\n"(131573Ch)Panax Notoginseng 013113d2 call DWORD ptr [__imp__printf (13182b0h)] - 013113d8 Add esp,14h the 013113DB CMP Esi,esp +013113DD Call @ILT +295(__RTC_CHECKESP) (131112Ch) A the Const intCK =9;//This control experiment is to observe that the effect of a reference to a constant CK +013113E2 mov dword ptr [CK],9 //Allocate stack space for constants, which is already in the symbol table - intIK =ck; $013113E9 mov dword ptr [IK],9 //see no, the reference to the constant CK is replaced directly with the value 9 of the constant, which is similar to the macro substitution, and the following experiment $ - intI1 =5;//This control experiment is to distinguish between constants and references to variables. -013113F0 mov dword ptr [I1],5 the intI2 = I1;//this refers to the variable i1, the i2 is assigned, and then see no, the constant I1 reference is not replaced with the value of I1, but to the stack to remove the value of I1 to the edx register, and then the value of MOV into the memory of the I2 - 013113F7 mov eax,dword ptr [i1]Wuyi 013113FA mov dword ptr [I2],eax the - return 0; Wu 013113FD xor Eax,eax -}
View Code
The analysis of the above experiment makes it easy to see that a reference to a collapsible constant is replaced with the value of the constant, whereas a reference to a variable requires access to the memory of the variable.
Summary: Constant folding says that in the compile phase, the variable is replaced with a value, and the constant has its own memory space, not like the macro definition does not allocate space, need to clarify this
I said a program that doesn't allow GCC to compile the C language, otherwise there is no problem of constant folding, first look at the results of the execution:
Finally, the const constants of the C language compiled by GCC are not optimized for constant folding, similar to the keyword of volatile before const constants. What is it exactly? Next blog post.
C + + constant folding (I.)