[英]extern keyword usage
我有三个程序,我使用extern
关键字。 我无法理解结果。 以下是三个例子:
示例1:我期望下面的代码会给出多次声明k
编译错误。 但它运作正常吗?
int k; //works fine
extern int k = 10;
void main()
{
cout<<k<<endl;
getchar();
}
示例2:当我尝试在上面的示例中初始化“k”时,编译器会出错。 为什么?
int k = 20; //error
extern int k = 10;
void main()
{
cout<<k<<endl;
getchar();
}
示例3:在此示例中,我更改了示例1中提到的定义顺序。当我编译此代码时,我收到错误。 为什么?
extern int k = 10;
int k; //error
void main()
{
cout<<k<<endl;
getchar();
}
示例2 :您尝试使用两个不同的值初始化全局变量两次。 这是错误。
示例3 :首先声明一个extern
变量,然后在同一个编译单元中定义一个具有相同名称的变量。 这是不可能的。
你应该使用**extern**
关键字,它的用途是引用超出当前范围的东西。
您还应该遵循适用于每个编译器的规则,而不是尝试使用某些编译器的异常,您的示例在我自己的编译器中给了我很多错误。
使用extern
引用而不是定义变量。
使用某种约定来进行外部命名。 我把所有外部作为首都,所以当我看到像MYVAR
这样的东西时,我知道它是全球性的。
将所有外部文件放在include头文件(.h)中并在cpp文件中执行#include
,这种方式更方便,有助于整理源代码。
请参阅此示例,其中我使用了所有3个规则:
unsigned short int AGLOBAL = 10; // definer and initializer
void MyFunc(void)
{
AGLOBAL+=1; // no need to include anything here cause is defined above
// more .....
}
// this is to include only once
#ifndef MYH
#define MYH
extern unsigned short int AGLOBAL; // no value in here!
#endif
#include globals.h
char SomeOtherFunc(void)
{
AGLOBAL+=10; // ok cause its declared by globals.h
// do more....
}
使用extern
关键字是告诉编译器:
变量在外部定义。
第一个程序应该给你一个错误。 你使用的是哪个编译器? BTW, void main()
不是标准的。 既不是C语言,也不是C ++语言。
你的编译器很草率。 编译这个微不足道的变化(包括标题和using
声明),我得到:
$ cat xxx.cpp
#include <iostream>
using namespace std;
int k; //works fine
extern int k = 10;
void main()
{
cout<<k<<endl;
getchar();
}
$ g++ -c xxx.cpp
xxx.cpp:5:12: warning: ‘k’ initialized and declared ‘extern’ [enabled by default]
xxx.cpp:5:12: error: redefinition of ‘int k’
xxx.cpp:4:5: error: ‘int k’ previously declared here
xxx.cpp:7:11: error: ‘::main’ must return ‘int’
$ g++ --version
g++ (GCC) 4.6.0
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$
你使用的是哪个编译器?
int k;
extern int k = 10;
这在C中是可以的,除了真实的定义之外,你可以有一个“暂定”。 在C ++中,它是不允许的。 在那里尝试两次声明相同的变量。
我的C编译器还警告我,同时进行extern
和初始化是不寻常的。
int k = 20; //error
extern int k = 10;
这试图给k
两个不同的值,这当然是行不通的。
extern int k = 10;
int k; //error
这似乎与案例1相同。它在C ++中是不允许的,但在C99中似乎是可以接受的。
案例1: 在c ++中给出重新定义错误(gcc-4.3.4)
案例2: 在c ++中给出重新定义错误(gcc-4.3.4)
案例3: 在c ++中给出重新定义错误(gcc-4.3.4)
在所有这三种情况下,您尝试使用外部链接定义名为k
的变量,并尝试在同一范围内定义另一个名为k
变量,这会生成Redefinition错误。
参考:
C ++标准:3.1声明和定义
3 [Example: all but one of the following are definitions:
int a; // defines a
extern const int c = 1; // defines c
int f(int x) { return x+a; } // defines f and defines x
......
在上面的代码片段中, a
和c
都是定义。
如果你的编译器没有给出所有这三种情况的错误,那么就C ++而言它就会被破坏。
对于第三个,你真的想要这个
extern int k = 10;
extern int k; //okay: this is just a declaration.
// extern int k = 4; re-define is no good.
void main()
{
cout<<k<<endl;
getchar();
}
您只能定义一次变量。 但是,您可以根据需要多次声明。
为了进一步说明, int i;
既是宣言又是定义。 通常,时间错误被认为是“定义”。 对于自动变量,声明和定义都在一个语句中完成。
所以当我们定义int k;
已分配名称参考为“k”的内存。 因此,当您尝试重新定义链接器时,链接器会抱怨。
int k;
extern int k = 3; // already defined in the previous statement
因此,这也是编译错误
extern int k = 3;
int k; // trying to redefine again - bad
这可能仅适用于C ++。 我不熟悉C,因此,我不能说C语言。在C ++中,即使我的解决方案也会抱怨,但不会对它产生错误。
请评判我并纠正我的错误。 我也在学习。
我理解了示例2和3.但是编译示例1的事实是如此奇怪。 gcc永远不会编译这样的代码。
首先,一个挑选。 你在谈论全局变量分辨率。 这是链接器的工作,而不是编译器。 虽然它没有真正意义,因为所有编译器套件通常也都使用链接器执行。
你应该知道的关于全局变量的是它们有两种:弱和强。 由于只能有一个具有给定名称的变量,如果有多个定义,链接器必须确定要使用哪个。 如果有多个字符串定义,则会出现错误。 如果存在单个强定义,则将其选择为规范定义,并且所有其他定义引用它。 如果只有弱定义,那么其中一个得到提升。
变量具有赋值的任何声明都被认为是强大的。 此外,如果没有赋值,则extern
关键字将强制变量引用另一个变量(如果存在的话)(实际上是弱者中最弱的)。
案例1:你有一个弱的声明,然后是一个强烈的声明。 这很酷。 案例2:你有两个强有力的声明。 错误! 案例3:你有一个强烈的声明,然后是一个弱的声明。 我真的不确定为什么这个失败了。 如果我猜测我会说第二个声明被链接器视为强大。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.