C++高级进阶 第四季:const详解(二) 常量折叠

简介:

一、文章来由

const详解之二

二、const 代替 #define

const最初动机就是代替 #define。

const 优于 #define:
(1) #define没有类型检查,const在编译期(而不是预编译期)做类型检查;

(2)const方便调试和定位bug。

所以应该完全用const代替#define

三、头文件中的const

(1)要使用const代替#define,同样需要把const定义放进头文件(或其他格式文件,include即可)。这样通过包含头文件,可把const定义单独放在一个地方并把它分配给一个编程单元。

(2)C++中的const默认为内部连接(internal linkage),也就是说 const 仅在被定义过的文件里才可见,而在连接时不能被其他编译单元看到。

但是在c中仅仅在另一个文件中定义(不用extern修饰),另一个文件也是合法的。c中const是必需分配内存的,而c++实际上一开始是不会分配内存的,只是存在字符表中。

//another.c
const int a = 5;

//other.c
#include <stdio.h>

int main()
{
    extern const int a;
    printf("%d\n",a);

    return 0;
}

(3)定义一个const时,必须赋一个值给它,除非用extern做说明:extern const int bufsize;

这里写图片描述

四、常量折叠(constant folding)

通常C++编译器并不为const创建存储空间,相反它把这个定义保存在它的符号表里,但extern强制进行了存储空间分配,取const地址也会**,这也解释了const详解(一)中可以修改const空间,但是cout原值相当于还是去符号表中找。

由于extern意味着使用外部连接(定义时使用extern),因此必须分配存储空间,这也就是说有几个不同的编译单元应当能够引用它,所以必须有存储空间。

通常情况下,当extern不是定义的一部分时,不会分配存储空间。如果使用const,那么编译时会进行常量折叠。

那同文件extern呢

extern const int a;
int main()
{
    //freopen("input.txt","r",stdin);

    cout<<a<<endl;

    return 0;
}

const int a = 66;

因为extern不是定义的一部分,所以个人认为这也不会分配空间。

五、为什么const要内部连接

当然想绝对不为任何const分配存储是不可能的,尤其是复杂的结构。所以const的定义必须默认内部连接,即连接仅在特定的编译单元内;否则,由于众多的const在多个cpp文件分配内存,引起连接错误。

连接程序在多个对象文件看到统一的定义就会“抱怨”。然而,因为const默认内部连接,所以连接程序不会跨过编译单元连接那些定义,因此不会有冲突。


参考资料

[1] c++编程思想

[2] http://blog.csdn.net/bestrivenfan/article/details/50951809

相关文章
|
10天前
|
并行计算 调度 C++
|
4天前
|
编译器 C++
【C++】【C++的常变量取地址问题(对比C的不同)】const修饰的常变量&volatile修饰用法详解(代码演示)
【C++】【C++的常变量取地址问题(对比C的不同)】const修饰的常变量&volatile修饰用法详解(代码演示)
|
6天前
|
安全 编译器 C++
【C++类和对象】const成员函数及流插入提取
【C++类和对象】const成员函数及流插入提取
|
7天前
|
编译器 C++
【C++进阶】引用 & 函数提高
【C++进阶】引用 & 函数提高
|
12天前
|
人工智能 C++
【重学C++】【指针】轻松理解常量指针和指针常量
【重学C++】【指针】轻松理解常量指针和指针常量
12 0
|
12天前
|
存储 C++
【C++进阶(九)】C++多态深度剖析
【C++进阶(九)】C++多态深度剖析
|
12天前
|
编译器 C++
【C++进阶(八)】C++继承深度剖析
【C++进阶(八)】C++继承深度剖析
|
12天前
|
编译器 C语言 C++
【C++进阶(七)】仿函数深度剖析&模板进阶讲解
【C++进阶(七)】仿函数深度剖析&模板进阶讲解
|
12天前
|
设计模式 C语言 C++
【C++进阶(六)】STL大法--栈和队列深度剖析&优先级队列&适配器原理
【C++进阶(六)】STL大法--栈和队列深度剖析&优先级队列&适配器原理
|
12天前
|
存储 缓存 编译器
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比
【C++进阶(五)】STL大法--list模拟实现以及list和vector的对比