在实现文件中不必要地使用extern?

时间:2016-10-02 18:00:43

标签: c

假设我们在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>

3 个答案:

答案 0 :(得分:2)

最简单的回答方法就是去测试它。

结果是 - 如果没有f的第一个声明,则会出现编译错误 - 初始化f时未定义符号array。所以区别在于struct foo fextern 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.hfimpl.c的命名风格,它没有暗示相关性 - 当然这可能是OP对问题的简化。

答案 2 :(得分:0)

通过在a.h中声明它,您已经表明它应该全局共享。

相反,extern用于表示该值来自外部位置。因此,当在同一文件中定义值时,这是毫无意义的。