不同文件之间的变量用const修饰时

来源:互联网 发布:访客网络开启安全吗 编辑:程序博客网 时间:2024/06/13 12:23

一个文件:test1.cpp

#include"stdafx.h"#include<conio.h>#include<stdlib.h>void func(void);extern const int j;extern const float i;int main(void){printf("%d  %f\n",j,i);getche();return 0;}

另一个写hao.cpp

#include"stdafx.h"extern const int j=7;extern const float i=1.3f;

发现hao.cpp如果j和i不加extern修饰的话显示    “无法解析的外部命令”错误,,,,而书上说定义全局变量时extern是可选的

而且在test1.cpp中extern声明中如果不加const也会显示同上的错误。

这个问题论坛上说:


Lactoferrin:很简单,因为int和const int不一样

lile1234_show:

在c++中const有限定变量作用域的作用,它限制变量只在本编译单元内可以使用.

heartszhang

没发完,不好意思。

从c++角度来说,楼主写法没问题,楼上的回答都不靠谱。

作为c++标准控,我用c++标准回答你。

首先,

extern const int j = 7;

是internal linkage还是external linkage?

答案是external。楼上很多人说const是internal,是的,const int j=7是internal但是extern const int j = 7是external。

C++标准规定,一个名字是internal linkage, 如果这个名字加了cosnt但是没有加extern。原文如下:

(A name having namespace scope (3.3.6) has internal linkage if it is the name of a variable that is explicitly declared const or constexpr and neither explicitly declared extern nor previously declared to have external linkage;)


所以extern const int j = 7是external linkage。


其次,为什么要在乎internal linkage还是external linkage呢?

因为c++标准规定:如果不同文件的2个名字都是external linkage,并且2个名字相同,那么他们是同一个名字。

所以楼主的const extern int j = 7和extern int j应该指代同一个东西。

标准原文如下,

Two names that are the same (Clause 3) and that are declared in different scopes shall denote the same variable, function, type, enumerator, template or namespace if 

— both names have external linkage or else both names have internal linkage and are declared in the same translation unit;


最后,关于楼主的链接错误。

test1.obj : error LNK2001: 无法解析的外部符号 "int j" (?j@@3HA)

这个链接错误说明linker无法找到j的定义。

我们再来看一下j是怎样定义的。

extern int j; //注意,这个不是j的定义,只是一个j的声明。

另一个文件,
extern const int j = 7; //这个才是j的定义。

关于声明和定义的区别就是声明只是告诉编译器这个名字存在,定义是告诉编译器真正的实体,如果要用这个名字的话,没有定义是不行的。例如,
int f(); //声明一个函数
int f() { return 0} //定义这个函数

为什么extern int j;不是定义呢?c++标准规定,如果加extern,同时又没有initialization的话,就是声明,否则就是定义。原文如下:

A declaration is a definition unless 
 - ...
 - ... it contains the extern specifier (7.1.1) or a linkage-specification25 (7.5) and neither an initializer nor a function body,

所以原因很清楚了,楼主的linker无法找到extern int j = 7;

或者是楼主编译器有问题,或者是楼主没有把extern int j = 7这个文件一起加进来编译。

cxsjabcabc

分析的不错,但是最后说的不对。声明在这个文件没有问题,外部也有定义,这就可行。
我在xcode的gcc4.2下面编译没有任何问题。
只能说这是编译器实现的不同,不是写的有问题。

hu7324829

链接时期错误, 比如说int j;在符号表里是_int_j_
const int j是_const_int_j_ 当然就找不到了

求解。。