How does a constCONSTconst guarantee that a variable cannot be modified in C?

We can think of two ways:

First, the compiler blocks statements that modify constConstconst variables so that the program cannot compile.

The second, prevented by the operating system, is to mark a constCONSTconst’s access to the memory address as “read-only.” If a running program tries to modify it, it will raise an exception and terminate the process.

Either way, the value of a variable cannot be changed. Which one? Let’s write two examples.

Let’s start with a simple example. The source file const.c:

Compile and receive a warning:

: $GCC -o const1 const1. Cconst. C: Infunction ‘main’ : const. C: because: Warning: initializationdiscards’ const qualifier from pointer targettype [- Wdiscarded – the qualifiers] int * p = & a;

Ignore it and run the program:

A running error is reported as a “segment fault”, which reminds us that the program accesses a certain area of memory with incorrect permissions. This indicates that the operating system has loaded the variable AAA into a read-only memory region, so a write to that region’s address will raise an exception, as determined by the operating system’s memory protection mechanism.

That is, the read-only property of constCONSTconst is implemented by the operating system, not by the compiler (the compiler only throws a warning, but does not prevent the compilation from passing).

Is that right? Not quite. Let’s look at another example, const2.c:

Compile, get the same warning:

: $GCC -o const2 const2. Cconst. C: Infunction ‘main’ : const. C: and: Warning: initializationdiscards’ const qualifier from pointer targettype [- Wdiscarded – the qualifiers] int * p = & a;

Ignore it and run the program:

Yi? How did it work, and the aaa value was changed?

Combining the above two examples, we can draw the following conclusion:

Constconstconst is just one of the C modifiers for variables. In this case, AAA is not so much a “constant” as a “variable not intended to be modified.” It is a syntactic declaration that tells the compiler “I don’t want to change it,” so the compiler checks syntactically for statements that change it (for example, “A =1;”). ), and will block you with an error if you find such “contrary” statements.

The compiler, however, only blocks changes to aaa, but not to the address. The source file const2.c only works because it bypassing the compiler’s syntactic checks by pointing to it with a pointer not called AAA.

For example, Zhou Shuren’s pen name is Lu Xun. The police only know to arrest Lu Xun. At this time, he can use one sentence: “What do you have to do with zhou Shuren? To fool them.

In this sense, constconstconst is used by the compiler only from syntactic checking, so there is a runtime loophole.

So why doesn’t const1.c work?

Looking closely at the two source programs, the difference is only that in CONST1.c aaa is declared as a global variable, whereas in CONST2.c it is declared as a local variable in main. The difference between global variables and local variables is that the former will be loaded before the program starts to run, and will remain in memory after loading, and the loading location in the data area until the program exits. The latter is loaded only when it is run to, in the run-time stack frame, and is reclaimed once it is out of scope.

Therefore, the compiler optimizes constintaconst\ int\ aconstinta declared as a global variable by placing it in a read-only memory area with the permission of readonlyRead \ onlyReadonly, Permission information is stored in the segment table maintained by the operating system. Every time a program accesses an address, the operating system checks whether its access permission is valid. Const2. C attempts to use the “write” access to “read only” section, nature will quote “segment fault” is wrong.

From this point of view, when AAA is a global variable, the compiler optimizes what is merely a “variable not intended to be modified” into a “true constant” and then gives the operating system the ability to maintain its immutable properties.

C is designed to let the compiler guarantee that constConstconst is invariant. This property has a loophole (we can trick the compiler into changing it by using Pointers), so when a const is a global variable (which is important because many source files access it), The compiler knows it can only manage compilation, not runtime, so it optimizes the statement to program true constants and lets the operating system’s memory protection do the job.

This optimization is not defined by C, but is a choice made by compiler manufacturers for practical purposes.

Welcome to exchange.

PS: In addition, for those who are learning programming or are working, if you want to improve your programming ability or even change industries, you can overtake on a curve and take a step faster! The author here may be able to help you ~

C language C++ programming learning exchange circle, QQ group [951258402] wechat official number: C language programming learning base

Share (source code, project actual combat video, project notes, basic introduction tutorial)

Welcome to change careers and learn programming partners, use more information to learn and grow faster than their own thinking oh!

Programming learning video sharing: