假设我们在C库中有一个引用extern
变量的标题:
A.H:
extern const struct foo f;
在库的实现文件中,我们找到了f
:
impl.c:
extern const struct foo f; // Is this `extern` really necessary?
static const struct foo *array[] = {
NULL,
NULL,
&f,
NULL
};
const struct foo f = { "alpha", array + 1 };
您会注意到f
的声明是第一位的,因此array
可以引用它,它也必须位于底部的f
定义之前,到array
。
无论如何,在 impl.c 中使用extern
是没有意义的,因为定义存在于同一个文件中?从 impl.c 中的extern
声明中删除f
是否会影响通过 a.h 使用此库的人?在删除 impl.c 中的extern
属性之前和之后,运行ABI检查显示没有区别。保留extern
是否有任何好处,或许向 impl.c 的读者表明,f
除了在下面定义/初始化之外,还要全局共享<style>
.hide-icegram {display:none !important}
</style>
<a href="tel:8888888888" class="clicktocall">8888888888</a>
<div class="icegram-popup"></div> <!--div inserted dynamically by icegram's script-->
<script>
jQuery(".clicktocall").click( function() {
jQuery(".icegram-popup").addClass("hide-icegram");
});
</script>
?
答案 0 :(得分:2)
最简单的回答方法就是去测试它。
结果是 - 如果没有f
的第一个声明,则会出现编译错误 - 初始化f
时未定义符号array
。所以区别在于struct foo f
和extern struct foo f
之间。实际上有一点点差异 - 它如何被放入数据段。
这可能是实现定义的,但是当我使用gcc时,在extern struct foo f
之后的第一个声明位置f
中使用array
,而没有extern
它会在它前面
或者您可以简单#include "a.h"
并通过预处理器将extern struct foo f
添加到impl.c
。
答案 1 :(得分:1)
在实施文件中不必要地使用
extern
?
也许它有一些神秘的价值 - 我认为它是多余的,应该从.c文件的顶部删除
无论如何, impl.c 中extern的使用没有意义,因为定义存在于同一个文件中?
不需要 impl.c 中的extern const struct foo f;
。考虑到更大的代码布局,它可能具有价值,因此具有一些文档价值。
从 impl.c 中的
f
声明中删除extern会影响那些通过 a.h 使用此库的人吗?
不,不是因为目前的编码。
将extern保留在那里是否有任何好处,或许向impl.c的读者表明f除了在下面定义/初始化之外还要全局共享?
这只是不必要的声明的通常用法。它可能是一组演化代码的结果。
我发现有问题的是a.h
,f
和impl.c
的命名风格,它没有暗示相关性 - 当然这可能是OP对问题的简化。
答案 2 :(得分:0)
通过在a.h
中声明它,您已经表明它应该全局共享。
相反,extern
用于表示该值来自外部位置。因此,当在同一文件中定义值时,这是毫无意义的。