我有两个问题:
//driver.c
#include <stdio.h>
#include <stdlib.h>
int lib_x = 1;
static void libc_func();
void libc_func(){
lib_x += 11;
}
int main(){
lib_x += 5;
printf("%d\n",lib_x);
libc_func();
printf("%d\n",lib_x);
return EXIT_SUCCESS;
}输出如预期的那样
6
17但是,当我切换时,代码是
//driver.c
#include <stdio.h>
#include <stdlib.h>
int lib_x = 1;
void libc_func();
static void libc_func(){
lib_x += 11;
}
int main(){
lib_x += 5;
printf("%d\n",lib_x);
libc_func();
printf("%d\n",lib_x);
return EXIT_SUCCESS;
}我得到一个编译错误,其中声明
driver.c:7:13: error: static declaration of ‘libc_func’ follows non-static declaration
static void libc_func(){
^~~~~~~~~
driver.c:5:6: note: previous declaration of ‘libc_func’ was here
void libc_func();我不明白为什么当一个非静态声明遵循一个静态声明()时没有出现错误,但是一个错误会反过来显示出来。有人能解释一下这种情况吗?
//driver.c
int lib_x;
static int lib_x = 2;
int main(){
return 0;
}错误是:
driver.c:3:12: error: static declaration of ‘lib_x’ follows non-static declaration
static int lib_x = 2;
^~~~~
driver.c:2:5: note: previous declaration of ‘lib_x’ was here
int lib_x;在编译此代码时:
//driver.c
static int lib_x;
int lib_x = 2;
int main(){
return 0;
}错误是:
driver.c:3:5: error: non-static declaration of ‘lib_x’ follows static declaration
int lib_x = 2;
^~~~~
driver.c:2:12: note: previous declaration of ‘lib_x’ was here
static int lib_x;因此,当非静态跟随静态&静态跟随非静态时,变量会显示错误。然而,函数只在静态跟随非静态时才显示错误.怎样才能解释变量和函数在处理上的差异呢?
发布于 2020-09-10 09:55:43
C的问题在于,当它在1989年标准化时,标准委员会必须注意编译器也将成功地编译许多在其约定中不同的现有代码。因此,关键字static和extern及其相互作用有点复杂。
int lib_x;是一个带有外部链接的暂定定义,而static int lib_x = 2;是一个具有内部链接的定义。然后,按照6.2.2p7,
7如果在翻译单元中,同一标识符同时出现在内部和外部链接中,则行为未定义。一些C编译器可能允许编译,但是编译器出错了。
至于
静态int lib_x;int lib_x = 2;
第一种是关于内部联系的初步定义,第二条规则比较复杂。
4对于在可见该标识符的先前声明的范围内用存储类说明符extern声明的标识符,31)如果先前的声明指定内部或外部链接,则后一声明中标识符的链接与先前声明中指定的链接相同。如果没有先前的声明可见,或者如果先前的声明指定没有链接,则标识符具有外部链接。
5如果函数的标识符声明没有存储类说明符,则其链接的确定与使用存储类说明符extern声明时完全相同。如果对象的标识符声明具有文件范围,且没有存储类说明符,则其链接是外部的。
因为它是,而不是,所以有一个存储说明符,它的链接将是外部。现在,令人困惑的是,如果确实使用了的extern存储类说明符,那么它就可以工作了!
静态int lib_x,extern int lib_x= 2;
extern声明的,也就是说,后者正好对应于
libc_func();静态libc_func(){ lib_x += 11;}
而且它不起作用,因为在没有任何事先声明的情况下,第一种方法会指定外部链接,而第二种方法指定内部链接;但是切换这2将是可行的,因为
静态空洞libc_func(){ lib_x += 11;} extern libc_func();
实际上,extern同样意味着“先前的链接,如果没有在*之前指定,则表示extern”。发布于 2020-09-10 07:42:41
要知道的是:当您声明变量时,外部链接是默认的,而声明总是在定义之前。
函数案例
在第一个例子中,首先将lib_func()声明为静态,然后定义它,而不指定存储分类器(静态或外部分类器)。但是,编译器知道,因为您以前声明lib_func()具有静态链接,所以不必“猜测”lib_func()存储分类器。
在第二种情况下,首先声明一个具有外部链接的变量(因为您没有再次指定存储分类器),但是编译器在lib_func()的定义中看到了一个静态存储分类器。由于宣言先于定义,所以这些定义是矛盾的。
https://stackoverflow.com/questions/63824248
复制相似问题