与 extern 关键字使用相关的疑问
AFAIK,应该使用 extern 关键字进行声明,并且任何值都不能与使用 extern 关键字声明的变量关联。但是假设我写了一条语句,例如
extern int i = 10;
编译器是否应该标记相同的错误?我见过一些编译器容忍并忽略这一点?为什么会这样呢? “C”标准对此有何规定?
编辑:@All,感谢您的回答。但我仍然有疑问。假设我在另一个文件(例如 ac)中定义了这个变量,而没有外部链接,并且我在 bc 中添加了这个语句,那么编译器不标记错误是否可以?它会被重新定义吗?
AFAIK, extern keyword should be used for declaration and no value can be associated with the variable being declared with extern keyword. But supposing I write a statement like
extern int i = 10;
Should the compiler flag an error for the same? I have seen some compilers being tolerant and ignoring this? Why is this so? What does the 'C' standard says about this?
EDIT: @All, Thanks for the answers. I have a doubt still though. Suppose I have the definition for this variable without the extern linkage in another file say a.c and I add this statement in b.c. Still is it Ok for the compiler not to flag an error? Does it come under redefintion?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
这是有效的语法,C99 标准中甚至有一个基本相同的示例。 (参见第 6.9.2-4 节。)
这些示例确实不是规范性的,但我相信它的目的是成为合法的语法。编译器经常会输出警告,因为它并没有真正完成任何事情。
4 示例 1
That's valid syntax, there is even an essentially identical example in the C99 standard. (See §6.9.2-4.)
It's true that the examples are not normative but I believe it was intended to be legal syntax. The compiler will often output a warning, because it doesn't really accomplish anything.
4 EXAMPLE 1
以下代码;
声明一个变量 i,但不实例化它。如果它没有在同一编译单元中定义,则链接器将尝试从构成最终可执行文件的目标文件和库中解析它。
但是,您的示例:
初始化对象,因此也必须实例化它。在这种情况下,
extern
关键字是多余的,因为对象是在同一编译单元(实际上是同一语句)中初始化的。它相当于:虽然在最后一个示例中 extern 关键字是多余的,但它与在头文件中声明全局变量并实例化时所拥有的完全相同> 在还包含该标头的源文件中(因为它应该允许编译器执行类型检查)。
您可以按如下方式测试:
对于未解析的变量 i,上述内容将导致链接器错误。而:
将毫无问题地链接。
The following code ;
declares a variable i, but does not instantiate it. If it is not also defined in the same compilation unit, the linker will attempt to resolve it from the object files and libraries that comprise the final executable.
However your example:
initialises the object, and therefore must also instantiate it. In this case the
extern
keyword is redundant because the object is initialised in the same compilation unit (in fact the same statment). It is equivalent to:Although in this last example the extern keyword is redundant, it is exactly equivalent to what you have when a global variable is declared in a header file, and instantiated in a source file that also includes that header (as it should, to allow the compiler to perform type checking).
You can test this as follows:
The above will cause a linker error for unresolved variable i. Whereas:
will link without problem.
extern
关键字指示给定变量分配在不同的模块中。它与对该变量的访问无关。分配给外部变量是完全合法的。The
extern
keyword indicates that the given variable is allocated in a different module. It has nothing to do with access to that variable. It's perfectly legal to assign to assign to an extern variable.extern
关键字的目的是为实体提供外部链接。无论它用在声明还是定义中都没有区别。您发布的代码绝对没有错误。如果您更愿意从“导出与导入”的角度来考虑,那么应用于非定义声明的
extern
关键字意味着我们导入< /em> 在其他翻译单元中定义的实体。当extern
关键字应用于定义时,意味着我们导出该实体以供其他翻译单元使用。 (尽管值得注意的是“导出与导入”并不完全是思考 C 链接概念的标准方式。)您不会经常看到定义中使用关键字的原因是因为在 C 文件范围中默认情况下,定义具有外部链接。因此,编写
是有效的,但是多余的,因为它相当于普通的
然而,在实际代码中,您有时可能会看到人们在函数声明和定义中使用此关键字,即使它在那里也是多余的
The purpose of
extern
keyword is to give the entity external linkage. Whether it is used in a declaration in a or definition makes no difference. There's absolutely no error in the code you posted.If you prefer to think about it in terms of "export vs. import", then
extern
keyword applied to a non-defining declaration means that we are importing an entity defined in some other translation unit. Whenextern
keyword applied to a definition, it means that we are exporting this entity to be used by other translation units. (Although it is worth noting that "export vs. import" is not exactly a standard way of thinking about the concept of C linkage.)The reason you won't see the keyword used in definitions very often is because in C file-scope definitions have external linkage by default. So writing
is valid, but redundant, since it is equivalent to plain
Yet, from time to time in the actual code you might see people using this keyword with function declarations and definitions, even though it is superfluous there as well