1

Summary

image.png

1) const is read-only, and the essence is still a variable. (Regardless of whether the value can be changed)

2) allocated space:
The const modified local variable allocates space on the stack.
The const modified global variable allocates space in the global data area (or read-only storage area). (These two points confirm that const modification is still a variable, because still allocates space in memory)

3) const is only useful at compile time, and is useless at runtime. (It means: const modified variable cannot be placed on the left side of the assignment symbol when compiled, but during the , the value of the variable can be changed through the pointer)

4) In modern C language compilers, modifying const global variables will cause the program to crash. Because modern C language compilers put const variables with global lifetimes in the read-only storage area, the content of the read-only storage area was changed, causing a crash. The standard C language compiler still puts the const variables of the global lifetime in the global data area, so they can be changed.

5) const modifies the function parameter, which means that does not want to change the value of the parameter in the function body (the parameter cannot appear on the left side of the assignment symbol).

6) The return value of the const modified function indicates that the cannot be changed, and is mostly used in the case of returning a pointer (the value pointed to by the pointer cannot be changed).

7) string literal is stored in read-only storage area, must use const char* to refer to the string literal (so that the error of modifying the read-only storage area literal will be reported at compile time); if it is only used char * , at this time compiled, will run into a segmentation fault.

8) Volatile tells the compiler that must go to the memory to remove the variable value each time; volatile is mostly used in the multi-threaded environment (variables may be changed in other threads or other places)

const and volatile

1、const

1.1 const modified variable

const int const_global_i = 1;  // const全局变量,全局生命期

int main()
{
    const static int const_static_i = 2; // static局部变量,全局生命期

    const int const_local_i = 3;        // 普通局部变量
    
//    const_local_i = 30;    // error,在编译期不允许出现在赋值符号左侧

    int* p = NULL;        // 标准C语法需要将要使用的变量先声明。
    
    p = (int*)&const_global_i;
    *p = 10;
    printf("const_global_i = %d\n", const_global_i);

    p = (int*)&const_static_i;
    *p = 20;
    printf("const_statici = %d\n", const_static_i);

    p = (int*)&const_local_i;
    *p = 30;
    printf("const_local_i = %d\n", const_local_i);

    return 0;
}
  • Under the bcc compiler ( standard C language compiler), this code can be compiled normally, the result of the test is that the values of the three variables have been changed, indicating that under the standard C compiler, all const defined read-only The value of the variable can be changed.
  • Under the gcc compiler (extended C compiler), this code can be compiled, but the following two assignment statements will segmentation fault at runtime. Explain that under the modern C language compiler, if the read-only variable defined global lifetime (such as global variables, static variables), the variable will be placed in the read-only storage area, and the modification will be Segfault.

      p = (int*)&const_global_i;
      *p = 10;
      printf("const_global_i = %d\n", const_global_i);
    
      p = (int*)&const_static_i;
      *p = 20;
      printf("const_statici = %d\n", const_static_i);

1.2 const modified function parameters

The const modified function parameter indicates that does not want to change the value of the parameter in the function body.

void func(const int a)
{
    a = 2;    // error, assignment of read-only parameter ‘a’
}

When the function parameter is modified with const, the value of the formal parameter cannot be changed inside the function.
Special: When the function parameter is a pointer, const still protecting a value of being unchangeable, following the principle of "numbering left and pointing right".

void func(const int* a)
{
    *a = 1; // error,指向的数不可改变,即*a不能作为左值
}

void func(int* const a)
{
    a = (int*)1; // error,指针不可改变,即a不可作为左值
}

1.3 const modified function return value

The return value of the const modified function indicates that the return value of cannot be changed, and mostly used in the case of returning a pointer.

const int* GetInt()
{
    int* p = (int*)malloc(4);
    *p = 1;

    return p;
}

int main()
{
    const int* p = GetInt();    // 返回值为const的指针,也必须const的指针来接
                                // 在编译层面保证函数返回的指针指向的值不可改变
    printf("*p = %d\n", *p);

    *p = 2;     // error,修改只读的值,read-only

    return 0;
}

It is mostly used return value of the 161348e21532d1 function is a pointer. This is because the memory returned by the general function is expected to be read-only and cannot be changed anywhere. If it is an ordinary variable, the function returns a copy of , and does not modify the value in the original memory.

1.4 What is the type of string constant?

The string literal C language is stored in the read-only storage area const char* pointer must be used in the program.
Understanding: The string literal is stored in the read-only storage area. Naturally, in the code, you also need to use the const keyword to specify its read-only attribute.

// 错误示例
char* p = "Delphi";        // "Delphi"是一个字符串字面量,存储于只读存储区

p[0] = 'a';                // runtime error,段错误。修改只读存储区的自然会崩溃
// 正确用法:使用了const之后,错误的赋值在编译期就会报出来
const char* p = "Delphi";    // 使用const显示说明"Delphi"字面量的只读属性

p[0] = 'a';                // compile error,修改只读变量的值

2、volatile

  • Volatile can be understood as "compiler warning indicator", prohibits compiler optimization
  • Volatile tells the compiler that must go to the memory to get the variable value every time
  • Volatile mainly modifies variables that multiple threads 161348e2153426
  • Volatile can also modify variables that may be changed by unknown factors
    Demo example

    int obj = 10;
    int a=0, b=0;
    
    a = obj;
    
    sleep(100);
    
    b = obj;
    • The compiler finds that obj not used as an lvalue during compilation, so will not change, so go directly to get its literal use, no need to access the memory, so "smart" (because CPU access Memory is a time-consuming operation. Since obj remains the same, it won’t be wrong to use it literally, and it’s faster, the best of both worlds).
    • But in fact, if this is a multi-threaded program, or a embedded interrupt handler, the value of obj is likely to be changed in a thread or an interrupt handler during sleep, this time directly It is wrong to use literal values.
  • Therefore, whether to use the volatile keyword, depends on the situation, because reading memory is time-consuming.

Small question: const voaltile int i = 0; what characteristics does the variable i have? How does the compiler handle this variable?
Answer: const makes the variable i have read-only properties, so it cannot be used as an lvalue in the program; volatile tells the compiler that every time it encounters a variable i, it must read the value in the memory that i represents.

This article is summarized from "C Language Advanced Course" by Tang Zuolin from "Ditai Software Academy".
If there are any errors or omissions, please correct me.


bryson
169 声望12 粉丝