【问题标题】:Two static variables in same name(two different file) and extern one of them in any other file同名的两个静态变量(两个不同的文件),其中一个在任何其他文件中
【发布时间】:2014-01-02 22:13:20
【问题描述】:

在一个文件中将变量声明为静态变量并在另一个文件中进行 extern 声明 - 我认为这会在链接时出错,因为 extern 变量不会出现在任何对象中,因为在其他文件中声明的变量是带有限定符静态。但不知何故,链接器(瑞萨)没有显示任何错误并创建了可执行文件。

如果上面的用例是正确的,如果 2 个变量在 2 个不同的文件中被声明为 static,而另一个在另一个文件中声明为 extern 会发生什么?在这种情况下,将在 2 个不同的对象中创建 2 个不同的内存,但是哪个变量将被链接到另一个变量在另一个文件中声明为 extern(因为两个变量名称相同)??

file1.c

static int test_var;
fn1()
{
   test_var = 1;
}    

file2.c

static int test_var;
fn2()
{
   test_var = 2;
}

file3.c

extern int test_var;
fn3()
{
   int x;
   x = test_var;
}

【问题讨论】:

  • @H2CO3,示例代码更新...
  • 声明为externtest_var 没有定义,main 也没有定义。我的链接器标记了这两个错误。请展示一个完整的示例。
  • 这应该给出一个链接器错误,在我的情况下它会出现(在 OS X 上使用 clang):架构 x86_64 的未定义符号:“_test_var”,引用自:file3.o 中的 _fn3
  • 该代码存在许多问题。我计算了 7 个警告以及链接器错误(_test_var 和 _main),只是默认警告(clang/OSX)

标签: c static extern


【解决方案1】:

在您的示例中,file3.c绝对无法访问 file1.cfile2.c 中的变量 test_var。如果test_var 未在file3.c 的范围内声明,您应该会收到链接错误。

【讨论】:

    【解决方案2】:

    答案可能是您配置了链接器的方式。如果您正在链接库,这里一切都会好起来的,file3.o 模块的test_var 引用为UNDEFINED

    如果您从这 3 个模块链接应用程序,您将失败,因为缺少 main() 例程定义和未解析的外部将被认为更不邪恶。 :-)

    只是为了检查它,请在您的构建过程中检查适当的*.o 模块符号表,然后检查最终结果。使用这种方法,您会发现奇怪的构建行为的原因。

    【讨论】:

      【解决方案3】:

      在file1.c和file2.c中,关键字static表示变量test_var文件作用域。这意味着这个变量只能在声明它的文件中访问。

      在file3.c中,关键字extern表示变量在其他文件中声明。

      当编译器编译file3.c时,它会标记变量test_var在其他目标文件中,并不关心它在哪里。所以这个文件可以编译,并且没有发生错误。 但是链接器在处理这个目标文件时,会发现没有test_var的变量可以链接到file3,就会报错。

      【讨论】:

      • static 表示静态链接,而不是文件范围,file3.c 中的extern 声明表示在其他地方有该变量的定义,该声明已经存在。
      • @effeffe 很抱歉我的错误,我再次阅读了 ISO 文档,你是对的。
      猜你喜欢
      • 1970-01-01
      • 2011-07-23
      • 2017-01-16
      • 2013-02-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多