在macOS中,我使用Visual Studio Code尝试编译C源代码。 (下面有3部分源代码)
head.h(已编辑)
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int add_number(int a, int b);
body.c
#include "head.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int add_number(int a, int b)
{
return a + b;
}
main.c
#include "head.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
int result = add_number (1, 2);
printf("%d", result);
return 0;
}
AND
gcc main.c
但是,当我按F5编译此C代码时, 发生以下错误:
Undefined symbols for architecture x86_64:
"_add_number", referenced from:
_main in main-49215f.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
是否链接失败消息? 有人帮我解决此错误吗? 例如,vsc设置或...
P.S。 我的vsc的task.json如下所示:
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "gcc build",
"command": "/usr/bin/gcc",
"args": [
"-g",
"-o",
"${fileDirname}/${fileBasenameNoExtension}",
"${file}"
],
"options": {
"cwd": "/usr/bin"
},
"problemMatcher":
{
"fileLocation": [
"relative", "${workspaceRoot}"
],
"pattern":
{
// The regular expression.
//Example to match: helloWorld.c:5:3: warning: implicit declaration of function 'prinft'
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
"group": "build"
},
{
"label": "execute",
"command": "cd ${fileDirname} && ./${fileBasenameNoExtension}",
"group": "test"
}
]
}
答案 0 :(得分:2)
是的,这是链接器的错误。原因是您通过以下方式构建了应用程序
gcc main.c
,其声明为add_number
(来自head.h),但没有定义,因为缺少实现该功能的模块/编译单元。快速解决方法是
gcc body.c main.c
答案 1 :(得分:1)
当你
inline int add_number(int a, int b); // head.h
int add_number(int a, int b) { ... } // head.c
extern int add_number(int a, int b); // main.c
然后问题仍然存在:代码有效,因为提供了add_number
的实现,前提是您像在其他答案中那样进行编译,即使用
gcc body.c main.c
如果您返回以前的编译,只有
gcc main.c
然后add_number
的实现仍然丢失。如果要内联函数,则从head.c
中删除实现,然后在head.h
中执行,如下所示:
static inline int add_number (int a, int b)
{
return a + b;
}
并从main.c
中删除原型(通常,在C模块中使用external
声明是一个坏主意,它们应转到标头,以便所有模块(包括标头)都同意原型)。
在特殊情况下,将add_number
从head.c
移到head.h
的内联函数后,C文件将为空,因此
gcc main.c
按预期工作。