Why C language global variable initialization elements must be constants, while local variables may not be constants

foreword

(1) I saw an interesting question today. In the communication group, a netizen asked why global variables cannot be given to variables. An initializer element is not constant error message will appear, the code is as follows

#include <stdio.h>

int a = 1;
int b = a+1; //这里会报错initializer element is not constant

int main(void)
{
    
    
	printf("a = %d\r\n",a);
	printf("b = %d\r\n",b);
	return 0;
}

(2) Generally speaking, global variables are given a constant number by default, and local variables are assigned to a variable. Regarding the above questions, I also expressed doubts, so I started to search for information with doubts.

#include <stdio.h>

int a = 1;

int main(void)
{
    
    
	int b = a+1;
	printf("a = %d\r\n",a);
	printf("b = %d\r\n",b);
	return 0;
}

explain

Global variable and local variable storage location

(1) To clarify this question, first of all, we need to know what is the difference between global variables and local variable storage? For more details, please refer to: Why is the initialized global variable stored in RAM when the RAM is obviously powered off and will lose data? Analyze the storage of the program in detail ;
(2) Because the above article is relatively large, I will condense it.
<1>A global variable that is assigned a value other than 0 will eventually be stored in the .data segment. When compiling, it will become RW-data, and its initial value needs to be stored in the ROM area.
<2>The local variable will not be compiled into the microcontroller, that is to say, it does not take up space when the microcontroller is powered off.
<3> When the microcontroller is powered on, a static data area will be allocated in RAM for global variables. At the same time, assign the initial value to the .data section of the static data area.
<4> After the MCU is powered on and starts running the program, the function where the local variable exists is called. The single-chip microcomputer will allocate space for the local variables in the stack, and then assign the initial value is implemented by executing the code during the running process.
<5> Therefore, we can draw a conclusion. A global variable that is assigned an initial value is statically stored. For local variables assigned initial values, the initial values ​​are stored dynamically.
(4) After understanding the above, we can understand why the initial value assignment of local variables can be passed, because it is dynamic, so the compiler will not care about it. But why not global variables? This involves the relationship between statically stored data and the compiler.

Compiler related

(1) We all know that the compiler can turn the C language into a 01 language that the machine can recognize. The compiler also has some functions that are often overlooked by us.
(2) In order to make the program more compact and refined, the compiler will help us deal with many things. This leads to a concept,Use compiler time for runtime time.
<1> Compile time: The period of time when you (the developer) compiles the code.
<2>Running time: the time period when the user runs your software.
(3) For example, the following simple code:
<1> We can find that int b = 2 + 3; after the conversion is called assembly code, he directly passes 5 to b. This means that the compiler has performed arithmetic processing and optimized the code. this is calledconstant folding.
<2> The operation of sizeof is the same, the compiler will directly pass the information that the int is 4 bytes to the variable.

insert image description here

(4) The above two examples use the time of the compiler to change the time of the running state. So after talking so much, what does it have to do with global variable initialization elements that must be constants?
(5) As mentioned above, the compiler will perform constant folding, but please note that this is constant folding! Constant folding will calculate constant expressions during compiler runtime, integer literals, sizeof() operator (when the parameter is not VLA), enumeration constants, and various arithmetic, relational/comparison operators in all operations When the numbers are all integer constants, the entire expression is considered an integer constant expression.

insert image description here

(6) However, we found out that the compiler will not perform variable operations! Therefore, the global variable int b = a+1; is assigned an initial value, and the compiler will not perform calculations!

Summarize

(1) Therefore, we can conclude:
<1> The compiler cannot obtain a non-constant value at compile time, it can only obtain the value of the variable indirectly by reading the variable address at runtime, and the global variable is in Its value must be determined at compile time.
<2> The initial value of the local variable is not managed by the compiler, it is assigned at runtime, so the initial value can be assigned to the variable.

Guess you like

Origin blog.csdn.net/qq_63922192/article/details/132312489