c与c++中的extern const的区别和联系
最近复习c++,发现了这个东西。
c语言里面,我们在一个.c文件中用const定义了一个全局变量后,可以在另一个.c文件中用extern const来引用,但在c++中在链接的时候会报undefined reference错误,这是因为在c语言里面,const全局变量在符号表里面是GLOBAL即全局可见的,而在c++里面却是LOCAL即只能在当前编译模块可见。
e.g.
在a.h中:
extern const int a;
在a.c中:
const int a = ;
在main.c中:
#include<stdio.h>
#include"a.h" int main()
{
printf("%d\n",a);
}
gcc a.c main.c -o main
编译成功,输入./main输出10
我们使用gcc -c a.c -o a.o生成a.o,再使用readelf -s a.o查看符号表:

可以看到最后一行,a在符号表中是GLOBAL的。
接下,我们不用改动代码,只是使用g++ a.c main.c -o main来编译程序,可以看到出错:

链接出错,原因是找不到a的定义,
使用g++ -c a.c -o a.o生成a.o,再使用readelf -s a.o查看符号表:

Num为6的那行表明,a变成了一个LOCAL对象,只能在a.o中可见,对main.o不可见。
解决方法:
将a.c 中的
const int a = 10;
改为:
extern const int a = ;
这样g++编译器在第一次看到a的定义的时候,因为存在extern关键字,就把它当成GLOBAL对象写入符号表:

c与c++中的extern const的区别和联系的更多相关文章
- C++中define与const的区别
C++中不但可以用define定义常量还可以用const定义常量,它们的区别如下: 用#define MAX 255定义的常量是没有类型的,所给出的是一个立即数,编译器只是把所定义的常量值与所定义的常 ...
- ES6中var/let/const的区别
let的含义及let与var的区别: let 声明的变量只在它所在的代码块有效: 如下: for (let i = 0; i < 10; i++) { console.log(i); } con ...
- c++中 #define和const的区别
来源参考:https://blog.csdn.net/yi_ming_he/article/details/70405364 这个区别用从几个角度来说: 角度1: 就定义常量说的话: const 定 ...
- Es6中let与const的区别:(神奇的块级作用域)
所谓的块级作用域:形成一个暂时性的死区:{ } 一.共同点: a:都是用来声明变量: b:都能形成一个块级作用域: c:都只能在声明变量的块级作用域里面有效: 二.不同点: 1.let: a:在 ...
- JavaScript中的var,const,let区别与用法(浅谈)
let 和 const是(ES6) 新增加了两个重要的 JavaScript 关键字. 1.var全局变量 //全局变量在 JavaScript 程序的任何地方都可以访问 //定义的变量可以修改,如果 ...
- extern const 不能一起用
转载至:https://www.cnblogs.com/herenzhiming/articles/5442893.html 常变量在定义的时候必须初始化,所以当你在a.cpp中定义extern co ...
- OC中的extern,static,const
const的作用: const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p). 被const修饰的变量是只读的. static的作用: 修饰局部变量: 1.延长局部变量的生命周期,程序结束才会 ...
- C++项目中的extern "C" {}
from:http://www.cnblogs.com/skynet/archive/2010/07/10/1774964.html C++项目中的extern "C" {} 20 ...
- C、C++中const的区别
C语言中: 被const修饰的变量,仍然是变量.虽然不能用C语法给这个变量改变值,但他本质上还是变量. C编译器会给它分配空间. C中,const默认使用的是外部链接. C++中: 被const修饰的 ...
随机推荐
- [51单片机] SPI nRF24L01 无线简单程序 1
main.c #include <reg51.h> #include <api.h> #define uchar unsigned char /**************** ...
- Linux服务器Cache占用过多内存导致系统内存不足问题的排查解决(续)
作者: 大圆那些事 | 文章可以转载,请以超链接形式标明文章原始出处和作者信息 网址: http://www.cnblogs.com/panfeng412/archive/2013/12/17/dro ...
- C#与数据库访问技术总结(七)综合示例
综合示例 说明:前面介绍了那么多,光说不练假把式,还是做个实例吧. 表:首先你要准备一张表,这个自己准备吧.我们以学生表为例. 1.ExecuteScalar方法 ExecuteScalar方法执行返 ...
- Javascript正则表达式的初步学习
<html> <head> <meta charset="utf-8"> <title>正则表达式的学习</title> ...
- Hadoop MapReduce例子-新版API多表连接Join之模仿订单配货
文章为作者原创,未经许可,禁止转载. -Sun Yat-sen University 冯兴伟 一. 项目简介: 电子商务的发展以及电商平台的多样化,类似于京东和天猫这种拥有过亿用户的在线购 ...
- 26数据查询的各种小玩法-select 下(必学)-天轰穿sqlserver视频教程
大纲:简单查询-选择数据列,使用字符串,改变列标题,使用数据运算,使用ALL语DISTINCT关键字,使用TOP关键字,排序 优酷超清地址,为了冲优酷的访问量,所以这里只放优酷的地址了,其实其他网站还 ...
- 关于C++ const 的全面总结
http://blog.csdn.net/Eric_Jo/article/details/4138548 C++中的const关键字的用法非常灵活,而使用const将大大改善程序的健壮性,本人根据各方 ...
- android: SQLite查询数据
掌握了查询数据的方法之后,你也就将数据库的 CRUD 操 作全部学完了.不过千万不要因此而放松,因为查询数据也是在 CRUD 中最复杂的一种 操作. 我们都知道 SQL 的全称是 Structured ...
- mac工具收藏
1.office字体兼容 http://mac.pcbeta.com/thread-32703-1-1.html
- ArrayList/Vector的原理、线程安全和迭代Fail-Fast
疑问 * ArrayList是非线程非安全的,具体是指什么?具体会产生什么问题?* ArrayList的内部原理是什么?为什么可以动态扩容?* Vector是线程安全的,具体是如何实现的?为什么不再推 ...