首页 > 编程语言 > 详细

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

时间:2021-09-15 16:43:08      阅读:5      评论:0      收藏:0      [点我收藏+]

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”

  技术分享图片

 

 

 

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 }

先看运行结果:

技术分享图片

 

 

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

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

技术分享图片

 

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

 

 

3、总结

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

 

 

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

 

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

原文:https://www.cnblogs.com/liwe1004/p/15267210.html

(0)
(0)
   
举报
评论 一句话评论(0
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!