常量折叠

 #include<iostream>
using  namespace  std;

void  main()

{

    const  int  a = 5;

    int *p = (int *)&a;                              //让p指向与a相同的内存空间

    cout << &a <<", " << p <<endl;

    *p = 10;                                             // 照里说a的值也应该改变,实际却没有,这就是常量折叠.

    cout <<a << ", " << *p <<endl;

    // 这个"常量折叠"就是在编译器进行语法分析的时候,将常量表达式计算求值,

    // 并用求得的值来替换表达式,放入常量表。可以算作一种编译优化。

    // 我只是改了这个地址内容,但是a还是,

    // 因为编译器在优化的过程中,会把碰见的const全部以内容替换掉

    // (跟宏似的: #define PI 3.1415,用到PI时就用.1415代替),

    // 这个出现在预编译阶段;但是在运行阶段,它的内存里存的东西确实改变了!!!

}


 

/* 看下面这句的反汇编代码

cout << a << ", " << *p << endl;

00B11547 mov         esi,esp

00B11549 mov         eax,dword ptr [__imp_std::endl (0B1A340h)]

00B1154E push        eax

00B1154F mov         edi,esp

00B11551 mov         ecx,dword ptr [p]

00B11554 mov         edx,dword ptr [ecx]

00B11556 push        edx

00B11557 push        offset string ", " (0B17800h)

00B1155C mov         ebx,esp

00B1155E push        1 // 关键看这一句,注意到输出打印a的值的时候传进去的并不是a

// 这个到底是哪来的,就是从我们的常量表里来的。

00B11560 mov         ecx,dword ptr [__imp_std::cout (0B1A344h)]

00B11566 call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0B1A32Ch)]

00B1156C cmp         ebx,esp

00B1156E call        @ILT+420(__RTC_CheckEsp) (0B111A9h)

00B11573 push        eax

00B11574 call        std::operator<<<std::char_traits<char> > (0B11159h)

00B11579 add         esp,8

00B1157C mov         ecx,eax

00B1157E call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0B1A32Ch)]

00B11584 cmp         edi,esp

00B11586 call        @ILT+420(__RTC_CheckEsp) (0B111A9h)

00B1158B mov         ecx,eax

00B1158D call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0B1A34Ch)]

00B11593 cmp         esi,esp

00B11595 call        @ILT+420(__RTC_CheckEsp) (0B111A9h)

总结:编译器会为常量分配了地址,但是在使用常量的时,常量会被一立即数替换(保护常量,防止被破坏性修改)


阅读更多
个人分类: C++
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭