转载自:http://xiangwangfeng.com/2011/05/02/const%E7%9A%84%E5%86%85%E9%83%A8%E9%93%BE%E6%8E%A5%E5%B1%9E%E6%80%A7/

  最早注意到这个问题也是很偶然:某天发现工程里面有个头文件定义了一堆的字符常量:

    const std::string sKeyCode                  =    "code";
const std::string sKeyResult = "result";
const std::string sKeyResults = "results";

  一时手贱,顺手把所有std:: string替换成了 char *,结果一跑:链接错误,XXXX重定义。百思不得其解,后来被人提醒这些变量都是全局变量啊,那用的时候应该是需要extern先声明一下。但是比较诡异的是:原来那种写法也是全局变量却不需要做另外的声明!

  查了一下,才明白原来const是默认具有内部链接属性(internal linkage),也就是说仅在定义这个变量的文件内可见,在链接时对外是不可见的。头文件里的全局常量实际上是include该头文件的CPP都有自己的一份额外的定义,而对于其他编译单元来说是透明的,不会造成重定义的链接错误。而至于改成const char*的写法,就需要注意了:这时候定义的只是一个指向常量字符串的普通指针而已,而不是常量指针(const修饰的是字符串,而非指针变量p,所以p在这里是全局的。如果const修饰的是指针变量p,则p链接时对外不可见)。正确的写法应该是const char* const或者const char xx[]。

  上面就是关于这个问题的一个简单分析,顺带顺藤摸瓜摸了些非主流的边角知识过来。

  const关键字具有内部链接属性,但是其“优先级”是低于extern的,如果我们以

    extern const int i = ;

  这样的语法来定义一个常量i时,这个i是具有外部链接属性的,换而言之在使用时需要注意先用extern声明。

  关于const修饰的变量地址:在通常情况下编译器是不会为const对象分配内存,只有在几种情况下会分配地址:

  1.extern和const同时使用,使得变量具有了外部链接属性。

  2.对const对象取地址—-我们知道常量一般是放到符号表中的,所以上面的情况即使各个编译单元有自己的额外定义,但是实际上还是存放在同一个地方,并不占额外空间。而当我们的程序对const对象取地址的时候才会强制分配内存地址:不同CPP里面定义的相同常量一般来说对他们取地址得到的结果应该是一样的。(至少MSVC中是这样的结果)

  3.runtime的const—-编译器是需要为它分配空间的,而且也不在符号表里面记录相关信息。

  最后补一句关于const char*这种写法的废话:

    const char* p = "hello";

  和

    char* q = "hello";

  这两种写法表达的意思都一样:指向hello这个常量字符串的指针。从C语言时代起后一种写法就是如此,而到了C++时代,为了兼容以前的程序所以做了同样的规定,但是const char*这种写法相对而言更正。

(转)const的内部链接属性(C++中适用)的更多相关文章

  1. C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型

    Technorati 标签: C,标识符,作用域,命名空间,链接属性,生命周期,存储类型,scope,name space,linkage,storage durations,lifetime 无论学 ...

  2. C语言中变量和函数的作用域和链接属性

    C语言中变量和函数的作用域和链接属性 作用域 代码块作用域: 代码块指的是使用"{}"包围起来的部分. 在代码块中定义的变量,代码块之外是不能访问的. 代码块嵌套之后的变量作用域, ...

  3. 7、存储类 & 作用域 & 生命周期 & 链接属性

    概念解析 存储类 存储类就是存储类型,也就是描述C语言变量在何种地方存储. 内存有多种管理方法:栈.堆.数据段.bss段..text段······一个变量的存储类属性就是描述这个变量存储在何种内存段中 ...

  4. C中的链接属性及作用域

    如果相同的标识符出现在几个不同的源文件中时,它们是表示相同的实体,还是不同的实体.标识符的链接属性决定如何处理在不同文件中出现的标识符.标识符的作用域与它的链接属性有关. 链接属性一般有三种:exte ...

  5. c语言3种链接属性: 外部(external), 内部(internal),无设置(none)

    c语言中,多个文件组合的时候,有可能标示名相同,那么这个时候编译器如何判别的呢?    c语言中有3种链接属性: 外部(external), 内部(internal),无设置(none)    外部( ...

  6. C语言中的作用域,链接属性和存储类型

    作用域 当变量在程序的某个部分被声明的时候,他只有在程序的一定渔区才能被访问,编译器可以确认4种不同类型的作用域:文件作用域,函数作用域,代码块作用域和原型作用域 1.代码块作用域:位于一对花括号之间 ...

  7. C语言中的作用域、链接属性与存储属性

    C语言中的作用域.链接属性与存储属性 一.作用域(scope) 代码块作用域 表示{}之间的区域,下例所示,a可以在不同的代码块里面定义. #include<stdio.h> int ma ...

  8. vue-learning:41 - Vuex - 第二篇:const store = new Vue.Store(option)中option选项、store实例对象的属性和方法

    vuex 第二篇:const store = new Vue.Store(option)中option选项.store实例对象的属性和方法 import Vuex from 'vuex' const ...

  9. phpcms导航中添加内部链接

    phpcms中栏目有3中类型 1.普通栏目 2.单网页 3.外部链接 其中如果想添加本站的内部链接,可以使用3,然后在添加链接的地方填入剩下的地址即可(需要以/开头) 如: /index.php?m= ...

随机推荐

  1. 署名|单位地址|Abstract

    科研论文写作---如何署名单位地址 署名的作者要研究结果负责,其署名作为对所作贡献的认可. 参与设计实验想法,参与实验过程,参与起草论文或重大修改论文,或对论文定稿的学者拥有署名权.而资金资助& ...

  2. MOOC(3)- python发送请求,返回的json数据被转码

    https://www.cnblogs.com/yoyoketang/p/10339210.html 问题:发送post请求,对post请求返回的json数据格式化,但是返回的结果被转码了 json. ...

  3. 吴裕雄--python学习笔记:sqlite3 模块的使用与学生信息管理系统

    import sqlite3 cx = sqlite3.connect('E:\\student3.db') cx.execute( '''CREATE TABLE StudentTable( ID ...

  4. yii2.0 集合七牛SDK 上传图片到第三方

    首先,请用composer下载七牛phpSDK (具体参考官方文档) composer require qiniu/php-sdk 注册七牛账号 获取 AK SK(密匙) ,创建资源对象 获取doma ...

  5. python登陆接口编写

    #coding:utf-8 import getpass,sys i=0 j=0 while i<3: username=raw_input('username:') #输入用户名 life_1 ...

  6. 在JavaScript里的“对象字面量”是什么意思?

    字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量.字面量分为字符串字面量(string literal ).数组字面量(array literal)和对象字面量(ob ...

  7. Flask向模板中JS传值简便方式

    后台传值: return render_template('statistics/numberofuserlogin/login_number.html', result_json = json.du ...

  8. Python scan查找Redis集群中的key

    import redis import sys from rediscluster import StrictRedisCluster #host = "172.17.155.118&quo ...

  9. Nginx+PHP配置错误,日志:[error] 24324#0: *31 FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream

    一.问题现象 1.安装nginx.php.php-fpm后,浏览器访问php报错,“File not found”: 二.问题排查 1.检查nginx.php-fpm服务是否正常启动,均正常启动: 2 ...

  10. 如何在NLP领域第一次做成一件事

    作者简介 周明,微软亚洲研究院首席研究员.ACL候任主席(president).中国计算机学会中文信息技术专委会主任.中国中文信息学会常务理事.哈工大.天津大学.南开大学.山东大学等多所学校博士导师. ...