zoukankan      html  css  js  c++  java
  • C++的常量折叠(三)

    背景知识

    在开始之前先说一下符号表,这个编译器中的东西。下面看一下百度百科中的描述:

    符号表是一种用于语言翻译器中的数据结构。在符号表中,程序源代码中的每个标识符都和它的声明或使用信息绑定在一起,比如其数据类型、作用域以及内存地址。
    符号表在编译程序工作的过程中不断收集、记录和使用源程序中一些语法符号的类型和特征等相关信息。这些信息一般以表格形式存储于系统中。如常数表、变量名表、数组名表、过程名表、标号表等等,统称为符号表。对于符号表组织、构造和管理方法的好坏会直接影响编译系统的运行效率。

    还有一个问题:前面说的似乎很让人烦,既然声明成了const,干嘛还老修改啊?

    根据C++标准,对于修改const变量,属于:未定义行为(指行为不可预测的计算机代码),这样一来此行为取决于各种编译器的具体实现(即不同编译器可能表现不同)。

    看到了吧,C++标准是不提倡这么玩的。

    下面看一下前面说的那个对照程序:

    int main()
    {
        int i0 = 11;
    
        const int i = 0;         //定义常量i
        int *j = (int *) &i;   //看到这里能对i进行取值,判断i必然后自己的内存空间
        *j = 1;                  //对j指向的内存进行修改
        printf("0x%p
    0x%p
    %d
    %d
    ",&i,j,i,*j); //观看实验效果
        
        const int ck = 9;     //这个对照实验是为了观察,对常量ck的引用时,会产生的效果
        int ik = ck;
    
        int i1 = 5;           //这个对照实验是为了区别,对常量和变量的引用有什么区别
        int i2 = i1;
    
        return 0;
    }

    同时把i的声明那条语句改成:

    const volatile int i = 0;         //定义常量i

    我们知道volatile是告诉编译器在翻译源码到汇编语言(机器码)的过程中,不要优化。把源码中对i的访问,翻译成每次都要去内存中抓取数据(这里是在做编译工作,只是把对应的源码翻译成汇编语言),而不是从符号表(常量表)中抓取数据。所以加上volatile关键字的i的访问都是去内存中拿数据,不去常量表中。

    现在还有个问题,如果我加上volatile关键字,那么每次对i的访问的语句都被翻译成了”去看内存里的数据“这种行为的汇编语言,不会有常量替换的过程了,那么下面的语句是不是合法了呢?

    i = 10

    你修改了常量的值,怎么可能合法呢?但是按照上面的说法对于const volatile int类型的i似乎又是合法的。问题出在了这里:

    编译器的一部分工作流程是这样的:语法检测->预编译(宏替换,常量替换,*(&i)恒等于i等优化)->编译。所以i = 10这句话在语法检查这个阶段,看到你对一个const常量赋值,就已经报错了,根本到不了编译这个阶段。

    但是有的一些编译器似乎无视这个volatile关键字,下面看一下测试的结果:

    (1)看vc6.0的结果:

    没有volatile关键字的:

    有volatile关键字的:

    即在VC++6.0编译环境下,在const变量定义时添加volatile修饰符,与不添加效果是一样的。编译器都采取了优化(甚至把编译器优化选项关闭还是如此,无奈了)。

    (2)vs2010和g++的测试结果是一样的:

    没有volatile关键字:

    有volatile关键字:

    所以:不建议修改const变量的值,即使修改也要熟悉当前使用的编译器对于该 未定义行为 是如何解释的

  • 相关阅读:
    How to maintain Oracle10g Recyclebin?
    C++函数
    巧算星期几
    如何把resin安装为Windows服务
    c++ try_catch throw
    PNG图片优化技术(一)
    内存回收专题
    [资料] 史上最强的伯克利大学1024线飞龙AI下载地址,有没有人有兴趣来测试一手?
    mmo游戏开发应在profile下运行,才能保证正式运行不卡
    Discuz多人斗地主积分版,消耗论坛积分的斗地主
  • 原文地址:https://www.cnblogs.com/stemon/p/4418043.html
Copyright © 2011-2022 走看看