我在主函数之后再次声明了全局变量,但它仍然影响主函数。我知道 C 允许在第一次声明不初始化变量时再次声明全局变量(它在 c++ 中不起作用)。如果我在 main 函数之后分配值,它仍然可以在 c 中有两个警告,但在 c++ 中会给出错误。
我已经调试了代码,但它从未到达int a=10;
行。
#include <stdio.h>
#include <string.h>
int a;
int main()
{
printf("%d",a);
return 0;
}
/*a=10 works fine with following warnings in c.
warning: data definition has no type or storage class
warning: type defaults to 'int' in declaration of 'a' [-Wimplicit-int]|
but c++ gives the following error
error: 'a' does not name a type|
*/
int a=10;
输出为10
。
几件事:
-
第一个
int a;
是暂定声明;第二个int a = 10;
是定义性声明。 -
a
是在文件范围内声明的,因此它将具有static
存储持续时间 - 这意味着它的存储将在程序启动时(main
执行之前)被搁置和初始化,即使定义声明发生在源代码的后面。 -
旧版本的 C 允许隐式
int
声明 - 如果变量或函数调用在没有声明的情况下出现,则假定它具有int
类型。C++不支持隐式声明,因此会出现错误。
这里
int a; /* global declaration */
编译器将上述语句视为声明而不是定义。它在其他翻译单元中查找a
的定义,它发现下面main()
int a=10;
因此,输出10
.
为避免警告,请使用extern
存储类声明a
extern int a;
来自 C 标准#6.9.2p2
2 声明具有文件范围而不带初始值设定项、没有存储类说明符或具有静态存储类说明符的对象标识符,构成暂定定义.....
所以,这个
int a;
是标识符a
的暂定定义。
关于暂定定义的几点:
- 如果同一翻译单元中没有定义,则暂定定义充当具有初始值设定项
= 0
的实际定义。 - 如果在同一翻译单元中较早或较晚地找到实际的外部定义,则暂定定义仅充当声明。
在您的程序中,编译器在同一翻译单元中找到了a
的定义:
int a=10;
因此,在使用 C 编译器编译时,您将获得输出10
。
现在,关于使用编译器编译时的错误C++:
如果您的程序中有此语句:
a=10;
使用编译器编译时C++这将出错,因为您缺少所需的类型说明符。但是这段代码将使用 C 编译器进行编译,因为在旧版本的 C (C89/90) 中,如果缺少类型说明符,则默认设置为int
。当然,使用 C99 和 C11 编译器编译时会收到警告消息,因为不再支持此隐式声明。
如果您的程序中有此语句:
int a=10;
C++没有暂定定义的概念,int a;
是C++中的定义。因此,由于一个定义规则的概念,C++编译器将给出错误 -redefinition of 'a'
。
据我所知,今天的C ++编译器无法运行代码:
int a;
int main()
{
printf("%d",a);
return 0;
}
int a=10;
也不
int a;
int main()
{
printf("%d",a);
return 0;
}
a=10;
因为 C++ 检测变量的双重声明。
并且
因为它无法初始化方法外部的变量。
错误"'a'不命名类型"是因为(第二个)错误,C++ 期望第一个单词是声明的类型(例如:int、long、char、-etc-),并给出变量。