【问题标题】:Unresolved symbol error未解决的符号错误
【发布时间】:2014-08-23 21:26:09
【问题描述】:

我正在使用 Visual Studio 2012 完成编程原理和实践中的练习。尝试编译下面的源代码时出现链接器错误:

unresolved symbol int foo.

我不明白为什么该符号未解析。

我的.h

extern int foo;
void print_foo();
void print(int);

我的.cpp

#include "my.h"
#include "../../std_lib_facilities.h"

void print_foo()
{
    cout<<foo<<'\n';
}

void print(int i)
{
    cout<<i<<'\n';
}

使用.cpp

#include "my.h"

int main(){
    int foo = 7;

    print_foo();
    print(99);
}

【问题讨论】:

  • 请正确格式化您的代码!
  • 您从未在全局命名空间中定义foo。 extern int foo; 只是一个声明,而不是一个定义。 foo 的唯一定义是 main() 中的局部变量。
  • foo 的全局定义是哪个文件有关系吗?
  • 是的,不。您可以在任一源文件(而不是标题)中定义它,并且代码将链接。是的;您应该在my.cpp 中定义它,因为它是my.h 和my.cpp 文件提供的接口的一部分。如果您有 6 个程序使用 my 包,您不希望每个程序都必须定义全局 foo。
  • T.C.非常感谢提供的信息非常有帮助。

标签: c++ header-files extern unresolved-external compilationunit


【解决方案1】:
extern int foo;

这是一个声明。它告诉编译器“在某处定义的全局命名空间中,将有一个名为 foo 类型为 int 的变量”。

int main(){    
    int foo = 7;
    // ...
}

这在函数main() 内部定义了一个int 类型的局部变量foo,并将其初始化为7。此局部变量在main() 之外不可见。

您没有做的实际上是在全局命名空间中定义 foo。为此,请将此行添加到 恰好一个 my.cpp 或 use.cpp 中,在包含之后:

int foo;

这在全局命名空间中定义了一个名为foo、类型为int 的变量。 (作为静态存储持续时间的对象,foo 默认初始化为零,但您也可以根据需要提供不同的初始化程序。)然后链接器应该能够解析对全局 foo 的引用。 print_foo() 当您将目标文件链接在一起时。

您只定义 foo 一次非常重要,尽管您可以声明任意多次。否则会违反单一定义规则,如果幸运的话会导致链接器错误,否则会导致未定义的行为。

【讨论】:

    【解决方案2】:

    此声明

    extern int foo;
    

    是名称 foo 的声明。这不是 foo 的定义。

    你必须初始化这个变量,它将是一个定义。例如

    extern int foo = 0;
    

    虽然我看不出你的代码有什么意义。

    也许您的意思如下。我认为是在模块中定义的变量,因为如果只有一个模块,我看不到使用标头的意义。

    /* my.cpp */
    
    #include "../../std_lib_facilities.h"
    
    extern int foo = 0;
    void print_foo();
    void print(int);
    
    void print_foo()
    {
        cout<<foo<<'\n';
    }
    
    void print(int i)
    {
        cout<<i<<'\n';
    }
    
    int main(){
    
        extern int foo;
        foo = 7;
    
        //...
    

    如果你想使用标题,那么代码可以看起来像

    /* my.h */
    
    extern int foo;
    void print_foo();
    void print(int);
    
    /* my.cpp */
    
    #include "my.h"
    #include "../../std_lib_facilities.h"
    
    
    int foo;
    
    void print_foo()
    {
        cout<<foo<<'\n';
    }
    
    void print(int i)
    {
        cout<<i<<'\n';
    }
    
    /* use.cpp */
    
    #include "my.h"
    
    int main(){
    
        extern int foo;
        foo = 7;
    
        print_foo();
        print(99);
    }
    

    【讨论】:

    • 您不必初始化变量来使其成为定义。 extern 表示“在别处定义”。定义就是int foo;。
    • 无论如何,将非内联函数或变量的定义放入标题中是个坏主意。
    • 定义变量的方法有多种。一种是 Vlad (extern int foo = 0;) 展示的技术;另一个是省略extern,留下int foo = 0;,而第三个将省略extern 和初始化程序(int foo; 在文件范围内)。当然,变量定义一定不能放在头中,因为如果放在头中,每个程序只有一个文件可以包含头,这首先使头毫无意义。
    • @Inspired 你说的很蠢。链接器发出变量未定义的错误。所以你必须定义它。
    • extern int foo; 在main()'. Header file my.h 中是不必要的`提供有关全局变量foo 的信息。
    猜你喜欢
    • 2012-03-20
    • 2011-09-03
    • 2010-11-20
    • 2014-05-12
    • 2014-05-14
    • 2011-10-21
    • 2012-10-21
    • 2014-10-03
    相关资源
    最近更新 更多