C++中const声明数据时的编译器优化问题

1、写在前面:

int main(void) {
    const int a = 0;
    int* ptr = const_cast<int*>(&a);

    *ptr = 10;

    int b = a;

    int c = b;

    cout << a << endl;
    cout << b << endl;
    cout << *(&a) << endl;
    cout << *ptr << endl;
    cout <<  (&a == ptr) << endl;

}

  对于以上代码,const声明了变量a为常量(伪常量),为什么叫伪常量呢?因为使用const_cast强制转换后,去掉其地址的const属性之后,使用ptr指针访问其地址并作修改,是合法的;真常量如p指向的内容为常量字符串,是不允许被修改的,但是同样的方法进行强制转换,编译不会报错,但是运行时,内核不会允许非法的写入操作,会抛出异常

const char* p=“hello world”

  C++中const声明数据时的编译器优化问题

 

 

 

2、分析const声明的常量的的实际优化过程:

对于这段代码,

 1 int main(void) {
 2     const int a = 0;
 3     int* ptr = const_cast<int*>(&a);
 4 
 5     *ptr = 10;
 6 
 7     int b = a;
 8 
 9     int c = b;
10 
11     cout << a << endl;
12     cout << b << endl;
13     cout << *(&a) << endl;
14     cout << *ptr << endl;
15     cout <<  (&a == ptr) << endl;
16 
17 }

先看运行结果:

C++中const声明数据时的编译器优化问题

 

 

 这里可以看到,标识符a对应的内存的数据其实已经被ptr给改了,但是直接使用标志符a去赋值或者输出的时候,并没有以按地址取值的方式从内存空间去读相应的数据,因此我们可以猜想,必然是在某个环节作了替换操作

2.1 看看这段代码预处理后的结果:并没有在预处理阶段作替换

C++中const声明数据时的编译器优化问题

 

2.2 再看看这段代码对应的汇编代码呢?:(虽然汇编没学过,但是对比来看可以看出区别)就是在编译阶段完成了替换将标识符a直接替换成了一开始声明的数值,而不是去先读取对应的地址空间存放的值;
C++中const声明数据时的编译器优化问题

 

 

3、总结

从以上的分析过程可以看出,const声明的数据类型的优化是存在编译器中的,减少了一步取址操作,也就是说,只要你使用const声明了一个数据类型(这里只验证了内置数据类型),那么编译器就认定它不会被修改,因此在编译阶段就对它进行数值替换(因为实际上使用标识符a作为左值去对它进行重新赋值时,是不被允许的,编译时就会报错)。然而由于它的一开始声明时需要实际的内存空间去存放数据,但是块空间本质上又是可以读写的,只是因为const的属性在语法上作了限制而已,其实际地址空间是可以间接操作的,所以才被称为伪常量

 

 

欢迎指正!转载请标明出处~   https://i.cnblogs.com/posts/edit;postId=15267210

 

上一篇:leetcode--单链表翻转


下一篇:多重继承下,注意父类指针new子类对象的相关问题