“编译为”设置为“默认”时的外部符号链接错误[重复]

Posted

技术标签:

【中文标题】“编译为”设置为“默认”时的外部符号链接错误[重复]【英文标题】:External symbol link error when "compile as" set to 'default' [duplicate] 【发布时间】:2016-01-01 07:56:35 【问题描述】:

我正在使用 Visual Studio 2013。我在 C 源文件 (file1.c) 中声明了一个全局变量,并在 C++ 源文件 (file2.cpp) 中定义的方法中使用。两个文件中包含的标头将变量声明为extern。项目属性C\C++ -> Advanced -> compile as 设置为defualt,根据文档,这意味着编译器使用文件扩展名来推断文件类型。此设置会导致 unresolved external symbol 链接错误。如果我将此选项设置为Compile as C codeCompile as C++ code,则项目编译和链接不会出错。我无法理解这种行为。 (顺便说一句,在 linux/GCC 下代码编译正常)。

这是重现问题的最小示例:

// file1.h
extern int g_i;

// file1.c
#include "file1.h"
#include "file2.h"

int g_i;
int main() 
    g_i = 1;
    foo();
    return 0;


// file2.h
#ifdef __cplusplus
extern "C"
#endif
void foo();

// file2.cpp
#include "file1.h"
#include "file2.h"

void foo() 
    int i = g_i;

【问题讨论】:

它在抱怨什么符号? g_i 的声明中是否需要extern "C"? (迂腐注意:file.c 没有声明变量 - 它定义它。头文件声明它。) @MartinBonner:它抱怨int g_i。我认为这很清楚,因为它是唯一的全局变量。 它可能一直在抱怨foo @MartinBonner:迂腐:两者实际上都是声明。实现文件中的那个也是暂定定义. 【参考方案1】:

语言链接适用于变量和函数。在 C 文件中,您定义了一个变量 g_i,它显然具有 C 语言链接(从 C++ 编译器的角度来看)。在 CPP 文件(或至少是头文件)中,您需要将变量声明为具有 C 语言链接。所以你需要的是:

// file1.h
#ifdef __cplusplus
extern "C"
#endif
extern int g_i;

或者,假设实际代码在头文件中有多个变量,您可能更喜欢:

// file1.h
#ifdef __cplusplus
extern "C" 
#endif

extern int g_i;
... // More declarations to taste

#ifdef __cplusplus

#endif

GCC 显然不区分变量的 C 和 C++ 链接(这是完全允许的)。

如果您强制将所有内容编译为 C 或强制将所有内容编译为 C++,那么当然变量的定义和变量的使用默认为相同的语言链接 - 所以它可以正常工作。

详情请见http://en.cppreference.com/w/cpp/language/language_linkage。特别是

...每个带有外部链接的变量名,都有一个名为 语言链接

【讨论】:

以上是关于“编译为”设置为“默认”时的外部符号链接错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

C代码编译为C++,但不是C [重复]

C ++ glfw未解决的外部符号错误[重复]

编译为 JavaScript 后 TypeScript 出现问题 - “重复标识符错误”

重复符号错误:SBJsonParser.o?

OpenCV for iOS 框架错误“Base.hpp”标头必须编译为 C++

链接错误重复符号