【问题标题】:Do different files have different scopes?不同的文件有不同的范围吗?
【发布时间】:2016-12-23 13:40:58
【问题描述】:

在 file1.cc 我写

int i = 0;

在 file2.cc 中我写

#include <iostream>

int i = 1;

int main()
{
  std::cout<< i << std::endl;
  return 0;
}

在 MacOS 中编译器报告

duplicate symbol _i in:
/var/folders/wn/q9648wb507j9l504vp2d_dwm0000gn/T/file1-bb8eca.o
/var/folders/wn/q9648wb507j9l504vp2d_dwm0000gn/T/file2-b5e667.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

但是不是说不同的文件有不同的作用域,这样我们就可以在file2中定义一个和file1同名的全局变量吗? 而且,如果不同的文件在同一个范围内,那么为什么将file2.cc转换为非法:

#include <iostream>

int main()
{
  std::cout<< i <<std::endl;
  return 0;
}

【问题讨论】:

  • 如果您希望全局变量具有内部链接(即仅在定义它们的文件中可见)- 将它们标记为static,或将它们放入匿名namespace
  • 你应该在 file2.cc 中有“extern i”
  • 一个全局变量是global——它无处不在。
  • 请注意,关于范围、可见性或生命周期的文件和语言规则是正交的。您真正要问的是不同翻译单元中的变量是否具有不同的范围。一个翻译单元通常由许多不同的文件组成——*.cc 或 *.cpp(或其他)文件和直接或间接使用#include 拉入的头文件。见stackoverflow.com/questions/1106149/…

标签: c++


【解决方案1】:

不允许对同一个全局变量进行多次定义。您必须将变量标记为staticconst,或将它们放置在匿名命名空间中。否则它们在全局范围内。

您的第二个问题:示例代码无法编译,因为编译器看不到另一个文件中的全局变量,因为编译器一次编译一个翻译单元(C++ 文件)。这就是为什么您需要添加extern i;。这告诉编译器,该变量将在另一个翻译单元中定义。

所有文件编译成功后,它们将被链接。链接器检查所有翻译单元。当您收到有关多个定义的错误时,链接期间会发生此错误。

【讨论】:

【解决方案2】:

在同一可执行文件中链接的文件的全局范围是相同的。为避免这种情况,您可以将其声明为 static,但在 c++ 中已弃用。
分隔两个文件范围的正确方法是使用namespaces

【讨论】:

    【解决方案3】:

    您的变量在同一范围内。您必须使用命名空间才能声明具有相同名称的变量。

    【讨论】:

    • 添加的示例有助于更好地阐明答案
    猜你喜欢
    • 1970-01-01
    • 2016-02-03
    • 2013-03-17
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多