“编译为”设置为“默认”时的外部符号链接错误[重复]
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 code
或Compile 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。特别是
...每个带有外部链接的变量名,都有一个名为 语言链接。
【讨论】:
以上是关于“编译为”设置为“默认”时的外部符号链接错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章
编译为 JavaScript 后 TypeScript 出现问题 - “重复标识符错误”