理解extern
extern有两层含义:表示声明和extern C
1、C++分为编译期和运行期,C++是分别单独编译,编译期可认为有三个步骤:a、预编译进行文本替换,将源文件(cpp文件)生成编译单元;b、编译单元经过编译生成目标文件(obj文件);c、所有目标文件连接生成库(dll文件)或者可执行文件(exe文件)。
2、在每个编译单元中,要使用一个对象,有两种方式:
a、在当前把它定义出来
b、告诉编译器,我有这个东西,但是它被定义在其他的编译单元,等到连接时找到它。这就是extern的第一个用法。
3、extern修饰对象,说明只是声明,对象定义在其他地方,连接的时候找到他。可以编译通过,但是,你引用的对象必须确实在其他的编译单元中,并且个对象必须允许你引用,否则连接出错。
4、考虑下面的需求,在一个编译单元内,我定义的对象,只想我自己使用,不给别人引用,该怎么办?
a、使用static修饰,表示内链接,不让别人连接。
b、使用匿名空间,虽然还是外连接,但是由于在匿名空间内,别人想连接也连接不上。
5、C++对象是一次定义,多次声明。这是有例外的。
a、考虑一次定义,首先确认一点,在一个编译单元内,不能重复定义。这也就是#ifndef/#define/#endif的作用
b、对于不同的编译单元之间,允许重复定义。包括下列情况:
static对象,const对象(没有extern),类定义,枚举定义,内联方法。
c、考虑,为什么这些情况,允许在不同编译单元重复定义,也就是内链接。
对于类定义和枚举定义,在编译单元编译的时候,必须知道对象占用多大内存,只有声明是不够的,必须知道定义。
对于内联方法,编译时进行文本替换,光有声明,没法替换。
对于static,const(没有extern),每人都有自己的一份,彼此没有关系。
e、考虑多次声明,对于类的成员方法和静态字段是不能重复声明的。
1、C语言没有重载,没有异常,没有模版。对于重载,C++编译器会进行名称重整,而C语言不会。那么问题来了,考虑C/C++混合编程,比如C++调用C语言的方法实现,编译时没错。C编译器生成还是原来的方法名,C++编译器对方法名重整,连接时名称对不上,连接出错。当然C调用C++的方法实现也是同样的道理。
2、该怎么解决这个问题?
问题的关键是,C++编译器进行了名称重整,而C编译器没有。要能相互调用,必须告诉C++编译器不要重整名称,还使用原来的名称。这就是要使用extern C
3、接口通过头文件体现,也就是同一份头文件。那么问题来了,对于C++编译器必须使用extern C,禁止名称重整。对于C编译器不认识extern C,不能有extern C,否则编译错误。该怎么办?
4、使用预编译,对于C++编译器有extern C {},对于C编译器没有extern C {},如下:
#ifdef _cplusplus
extern C
{
#endif
...
...
...
#ifdef _cplusplus
}
#endif
理解extern的更多相关文章
- 理解extern char s[100]与extern char *s
在x.c中定义了一个字符数组 char s[100],在l.c中进行引用extern char s[200], 有些c程序新手经常把它写成extern char *s. 这两种写法的含义一样吗? 首先 ...
- 深入理解extern使用方法
一. extern做变量声明 l 声明externkeyword的全局变量和函数可以使得它们可以跨文件被訪问. 我们一般把全部的全局变量和全局函数的实现都放在一个*.cpp文件中面,然后用一个同名的 ...
- 【转载】理解C语言中的关键字extern
原文:理解C语言中的关键字extern 最近写了一段C程序,编译时出现变量重复定义的错误,自己查看没发现错误.使用Google发现,自己对extern理解不透彻,我搜到了这篇文章,写得不错.我拙劣的翻 ...
- static/extern&const个人理解
//const仅仅用来修饰右边的变量(基本数据变量p,指针变量*p) static NSString *const keyA = @"keyA"; static NSString ...
- 再议extern和include的作用
先引入一下题啊,主要是看到有人这样写 我个人觉的这样写没什么意思,没有体现出了extern的特性. 为什么我要这样说,先谈谈include,总是有人觉得这个东西很神秘,很特殊不知道他干了什么.其实 ...
- C++之宏、extern关键字与多线程
理解C++ 宏 1.特殊字符 考虑下面的需求,程序中多处使用文本字符串.我们知道文本字符串前后都要加上双引号,我很讨厌输入双引号.有没有好的办法呢?根据常识,使用下面的宏: #define Str(x ...
- extern关键字详解
基本理解 extern放在变量或者函数之前,表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义. extern有两个作用 1.当它与"C"一起连 ...
- C语言_了解一下C语言中的四种存储类别
C语言是一门通用计算机编程语言,应用广泛.C语言的设计目标是提供一种能以简易的方式编译.处理低级存储器.产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言. C语言中的四种存储类别:auto ...
- (七十六)CoreLocation(二)获取经纬度、速度、方向,进行区域监听
上节说明了如何在iOS7和iOS8上完成授权,并且开始获取位置,这一节介绍获取位置信息的方法. [定位精度] 定位精度有多种选择:根据字面意思即可理解 extern const CLLocationA ...
随机推荐
- uestc 1722 吴神的表白
// 这题做的我好难过 不是因为没有思路 而是因为超数据类型范围的事// ax+by=c a,b,c>0// 那么该直线经过 1 2 4三个象限// 2 4 象限的第一整数解肯定是该象限最优解/ ...
- Java基础——异常处理
异常的层次结构 所有的异常类都是 java.lang.Exception 类的子类型.异常类都是 Throwable 类的子类.除了异常类 Error 类也是由 Throwable 类产生的的子类1. ...
- Java单例模式和volatile关键字
单例模式是最简单的设计模式,实现也非常"简单".一直以为我写没有问题,直到被 Coverity 打脸. 1. 暴露问题 前段时间,有段代码被 Coverity 警告了,简化一下代码 ...
- .NET面试题系列
索引: .NET框架基础知识[1] - http://www.cnblogs.com/haoyifei/p/5643689.html .NET框架基础知识[2] - http://www.cnblog ...
- UI篇--布局问题
1.android:layout_marginRight 不起作用解决方法 今天想在RelativeLayout的左右分别放上一个按钮, 左边按钮用marginLeft="10dp" ...
- ubuntu下安装selenium2.0 环境
参考:http://www.cnblogs.com/fnng/archive/2013/05/29/3106515.html ubuntu 安装过程: 1.安装:setuptools $ apt-ge ...
- HDU5787 K-wolf Number 数位dp
分析:赛场上也知道是裸的数位dp,但是无奈刷数位dp题刷的太少了,并不能写出来 一点感想:赛后补题,看了题解的map记录状态,一脸蒙逼,也是非常的不爽,然后想看别人写的,不是递归就是写的比较乱 而且我 ...
- Qt使用Cookies对网站操作之Get和POST
1.添加QNetwork模块: a.Qt Creator中打开.pro文件添加QT+=Network; b.VS_Qt中项目属性中Qt Project Settings中Qmodules中勾选”QNe ...
- C++实现网格水印之调试笔记(五)—— 提取出错
在实现提取水印的过程中,遇到了一些问题 首先还是根据论文中的思路来梳理一下整个提取流程 读入两个模型,一个原始模型ori_mesh, 一个水印模型wm_mesh. 将两个模型对齐(即放在同一个坐标系下 ...
- XAMPP:访问phpmyadmin出错的解决方案
来源:http://www.ido321.com/1246.html XAMPP(Apache+MySQL+PHP+PERL)是一个功能强大的建 XAMPP 软件站集成软件包,轻巧,用起来很方便.它提 ...