我一直在研究何时可以在全局范围内混合使用extern
, static
和no storage specifier声明的变量。 结果让我很困惑。
这是我发现的(每个段落是一个单独的编译单元):
/* ok */ int x; int x; /* ok */ int f(); int f(); /* ok */ int x; extern int x; /* ok */ int f(); extern int f(); /* error: static declaration follows non-static declaration */ int x; static int x; /* ok (no warning) */ int f(); static int f(); /* ok */ extern int x; int x; /* ok */ extern int f(); int f(); /* ok */ extern int x; extern int x; /* ok */ extern int f(); extern int f(); /* error: static declaration follows non-static declaration */ extern int x; static int x; /* error: static declaration follows non-static declaration */ extern int f(); static int f(); /* error: non-static declaration follows static declaration */ static int x; int x; /* ok (no warning) */ static int f(); int f(); /* ok */ static int x; extern int x; /* ok */ static int f(); extern int f(); /* ok */ static int x; static int x; /* ok */ static int f(); static int f();
我用gcc
和clang
获得了相同的结果,但是我找不到一个有效的模式和无效的模式。
这里有什么逻辑吗?
关于将所声明的全局声明与extern
, static
和no存储说明符混合,C标准有何说法?
如果您定义不带关键字static
的标识符,它将在对象文件中发布,并可由其他模块访问。 因此,如果您再次在另一个模块中定义没有static
标识符,则会产生冲突:两个已发布的标识符。
如果您使用关键字
static
,则(大部分)其余部分不适用。
问题是声明标识符和定义标识符之间的区别。 第一个说“将有一个这种类型的标识符X
”。 第二个说“这就是我将要称之为X
的东西”。
这就是为什么在头文件中所有变量都应该显式声明为extern
或static
:
首先,在标准C中没有任何称为“全局”的东西,它是一个经常被误用的术语,可能意味着几个不同的东西。
如果在文件范围 (您称之为“全局”)声明某些内容并且未指定存储类,则默认为外部链接。 您无法在文件范围内声明没有链接的内容。 这由C11 6.2.2规定。
变量(强调我的):
如果对象或函数的文件范围标识符的声明包含存储类说明符static,则标识符具有内部链接。
对于在该标识符的先前声明可见的范围内使用存储类说明符extern声明的标识符,如果先前声明指定内部或外部链接,则后面声明中的标识符的链接与链接相同在先前声明中指明。 如果没有先前声明可见,或者先前声明未指定链接,则标识符具有外部链接。
function:
如果函数的标识符声明没有存储类说明符,则确定其链接与使用存储类说明符extern声明的完全相同。 如果对象的标识符声明具有文件范围而没有存储类说明符,则其链接是外部的。
以上就是c/c++开发分享在全局范围内将声明与extern,static和no存储说明符混合使用相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/549269.html