In the following code, why do multiple declarations (and one definition) work fine for a global variable x
but not for a local variable y
which is inside the main()
function? It shows the following 2 errors:
在下面的代码中,为什么多个声明(和一个定义)适用于全局变量x而不适用于main()函数内的局部变量y?它显示以下2个错误:
1) redeclaration of 'y' with no linkage
1)没有联系的'y'重新声明
2) previous declaration of 'y' was here
2)之前的'y'声明就在这里
Why is it showing error for the local variable but not global variable? Not only my book, but the following 2 links from this forum clearly state that we can declare a variable multiple times (though define only once).
为什么它显示局部变量但不是全局变量的错误?不仅是我的书,而且本论坛的以下2个链接清楚地表明我们可以多次声明一个变量(尽管只定义一次)。
And kindly take care to explain what does the "with no linkage" part of the first error "redeclaration of 'y' with no linkage" mean? What linkage and to whom? Where would a local variable be linked?
并且请注意解释第一个错误“没有连接”的部分“没有连接的'y'的重新声明”是什么意思?什么联系和谁?局部变量在哪里链接?
#include<stdio.h>
int x;
int x;
int x=303;
int main(void)
{
int y;
int y;
int y=776; //Works fine if above 2 declarations are removed!!
printf("The value of x is %d,and of y is %d",x,y);
}
3 个解决方案
#1
19
In C and C++, int y;
within a function is both a declaration and a definition.
在C和C ++中,int y;函数内部既是声明又是定义。
In C, int x;
in the file scope (outside any function) is a declaration and a tentative defintion. Multiple tentative definitions are allowed; only one definition is allowed.
在C中,int x;在文件范围内(任何函数之外)是一个声明和一个暂定的定义。允许多个暂定定义;只允许一个定义。
#2
5
This is the way defined in the C99 standard, section 6.2.2, part 2:
这是C99标准第6.2.2节第2部分中定义的方式:
In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.
在构成整个程序的翻译单元和库的集合中,具有外部链接的特定标识符的每个声明表示相同的对象或功能。在一个翻译单元内,具有内部链接的标识符的每个声明表示相同的对象或功能。没有链接的标识符的每个声明表示一个唯一的实体。
The "global" variables x
have external linkage, so they denote the same object. The local y
variables, on the other hand, has no linkage, so there is a collision.
“全局”变量x具有外部链接,因此它们表示相同的对象。另一方面,局部y变量没有连接,因此存在冲突。
References: C99 Standard.
参考文献:C99标准。
#3
3
With external variables, any declaration that isn't an initialisation is a tentative definition. These by themselves don't create any storage, so multiple ones are allowed. So taking your example:
对于外部变量,任何非初始化的声明都是暂定的。这些本身不会创建任何存储,因此允许多个存储。以你的榜样为例:
int x; // tentative def
int x; // and again -- ok
int x=303; // definition -- ok
int x=303; // multiple definition -- error
If at the end of the file there have been only tentative definitions, the variable is defined once, and set to 0.
如果在文件末尾只有暂定定义,则变量定义一次,并设置为0。
This means that if you link to another file which also has a tentative definition of x
, you'll have an error according to the standard. Most compilers/linkers have always allowed this, though, and it's defined in the standard as an extension.
这意味着如果您链接到另一个同时具有x的暂定定义的文件,则根据标准会出现错误。但是,大多数编译器/链接器总是允许这样做,并且它在标准中被定义为扩展。
With local variables, each declaration is a definition because of scope rules. This, however, is allowed:
对于局部变量,由于范围规则,每个声明都是一个定义。但是,允许这样做:
void func(void)
{
int y = 0;
{
int y = 1; // a completely different y
}
}
#1
19
In C and C++, int y;
within a function is both a declaration and a definition.
在C和C ++中,int y;函数内部既是声明又是定义。
In C, int x;
in the file scope (outside any function) is a declaration and a tentative defintion. Multiple tentative definitions are allowed; only one definition is allowed.
在C中,int x;在文件范围内(任何函数之外)是一个声明和一个暂定的定义。允许多个暂定定义;只允许一个定义。
#2
5
This is the way defined in the C99 standard, section 6.2.2, part 2:
这是C99标准第6.2.2节第2部分中定义的方式:
In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.
在构成整个程序的翻译单元和库的集合中,具有外部链接的特定标识符的每个声明表示相同的对象或功能。在一个翻译单元内,具有内部链接的标识符的每个声明表示相同的对象或功能。没有链接的标识符的每个声明表示一个唯一的实体。
The "global" variables x
have external linkage, so they denote the same object. The local y
variables, on the other hand, has no linkage, so there is a collision.
“全局”变量x具有外部链接,因此它们表示相同的对象。另一方面,局部y变量没有连接,因此存在冲突。
References: C99 Standard.
参考文献:C99标准。
#3
3
With external variables, any declaration that isn't an initialisation is a tentative definition. These by themselves don't create any storage, so multiple ones are allowed. So taking your example:
对于外部变量,任何非初始化的声明都是暂定的。这些本身不会创建任何存储,因此允许多个存储。以你的榜样为例:
int x; // tentative def
int x; // and again -- ok
int x=303; // definition -- ok
int x=303; // multiple definition -- error
If at the end of the file there have been only tentative definitions, the variable is defined once, and set to 0.
如果在文件末尾只有暂定定义,则变量定义一次,并设置为0。
This means that if you link to another file which also has a tentative definition of x
, you'll have an error according to the standard. Most compilers/linkers have always allowed this, though, and it's defined in the standard as an extension.
这意味着如果您链接到另一个同时具有x的暂定定义的文件,则根据标准会出现错误。但是,大多数编译器/链接器总是允许这样做,并且它在标准中被定义为扩展。
With local variables, each declaration is a definition because of scope rules. This, however, is allowed:
对于局部变量,由于范围规则,每个声明都是一个定义。但是,允许这样做:
void func(void)
{
int y = 0;
{
int y = 1; // a completely different y
}
}