Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用makefile编译gcc时出现链接错误_C_Gcc_Linker_Makefile - Fatal编程技术网

使用makefile编译gcc时出现链接错误

使用makefile编译gcc时出现链接错误,c,gcc,linker,makefile,C,Gcc,Linker,Makefile,(在继续之前,缺少frees和写入代码中从未使用过的变量, 用于测试工具) 我编写了这样的代码,并且生成了这样的文件: 未读 #ifndef __UNREAD_TWO_H #define __UNREAD_TWO_H const int SIZEOF_INT = sizeof(int); int addTwo(); 未读 #include <stdio.h> #include <stdlib.h> #include "unread_two.h" int main(

(在继续之前,
缺少frees和写入代码中从未使用过的变量,
用于测试工具)

我编写了这样的代码,并且生成了这样的文件:

未读

#ifndef __UNREAD_TWO_H
#define __UNREAD_TWO_H

const int SIZEOF_INT = sizeof(int);
int addTwo();
未读

#include <stdio.h> 
#include <stdlib.h>
#include "unread_two.h"

int main(int argc, char *argv[])
{
    int *x;

    x = (int *)malloc(SIZEOF_INT);
    x = addTwo();
    free(x);

    return 0;
}
我应该解决什么问题?

您不应该在头中定义
SIZEOF_INT
,否则,您将在多个编译单元中包含此头时得到多个定义,如您所见。而是在头文件中声明它,并在源文件中定义它:

// unread_two.h

extern const int SIZEOF_INT;         // *declare* SIZEOF_INT


或者,在这种特殊情况下,您可能有理由使用“old skool”方法,使用宏:

// unread_two.h

#define SIZEOF_INT sizeof(int)
您不应该在头中定义
SIZEOF_INT
,否则,您将在多个编译单元中包含此头时获得多个定义,如您所见。而是在头文件中声明它,并在源文件中定义它:

// unread_two.h

extern const int SIZEOF_INT;         // *declare* SIZEOF_INT


或者,在这种特殊情况下,您可能有理由使用“old skool”方法,使用宏:

// unread_two.h

#define SIZEOF_INT sizeof(int)
实际上您有两个错误,一个是您报告的错误,另一个是更狡猾的错误

出现错误的问题是,在包含头文件的所有源文件中都定义了常量
SIZEOF_INT
。Include guards(包含保护)仅可防止在同一源文件(或从技术上说是翻译单元)中多次包含,但不会阻止您在多个源中包含同一文件。这意味着编译器将在
unread\u twomain.o
unread\u twoo.o
中创建
SIZEOF\u INT
的定义,链接器将对此进行投诉

解决方法是只在头文件中声明常量,然后在单个源文件中定义它


另一个问题是在
main
中创建
x
作为指针,并为其分配内存(顺便说一句,您不应该键入
malloc
的返回值),然后将
addTwo
的结果分配给该指针。但是
addTwo
不返回指针,它返回一个直接的值,所以你让指针
x
指向地址
6
,我想这并不是你想要做的。当您尝试释放
x
指向的内存时,这将导致未定义的行为,很可能导致崩溃

在您的程序中,您根本不必使用指针。只需使用普通的非指针变量:

int addTwo()
{
    int y = 3;
    int sum = y + y;

    return sum;
}

实际上您有两个错误,一个是您报告的错误,另一个是更狡猾的错误

出现错误的问题是,在包含头文件的所有源文件中都定义了常量
SIZEOF_INT
。Include guards(包含保护)仅可防止在同一源文件(或从技术上说是翻译单元)中多次包含,但不会阻止您在多个源中包含同一文件。这意味着编译器将在
unread\u twomain.o
unread\u twoo.o
中创建
SIZEOF\u INT
的定义,链接器将对此进行投诉

解决方法是只在头文件中声明常量,然后在单个源文件中定义它


另一个问题是在
main
中创建
x
作为指针,并为其分配内存(顺便说一句,您不应该键入
malloc
的返回值),然后将
addTwo
的结果分配给该指针。但是
addTwo
不返回指针,它返回一个直接的值,所以你让指针
x
指向地址
6
,我想这并不是你想要做的。当您尝试释放
x
指向的内存时,这将导致未定义的行为,很可能导致崩溃

在您的程序中,您根本不必使用指针。只需使用普通的非指针变量:

int addTwo()
{
    int y = 3;
    int sum = y + y;

    return sum;
}


最快的解决方法是在头文件中的
SIZEOF_INT
定义前面添加
static
(但这不太可能是一个好的长期解决方案,因为可能会导致两个对象文件在SIZEOF_INT的实际值上存在分歧)。在C++中,常量将被有效地处理,但是C创建两个初始化变量,每个源文件一个,并且不能将这两个源文件链接在一起。最快的解决方案是在代码的定义前面添加<代码>静态< /代码>。(但这不太可能是一个好的长期解决方案,因为最终可能会有两个对象文件在SIZEOF_INT的实际值上存在分歧)在C++中,常数将被有效地处理,但是C创建两个初始化变量,每个源文件一个,并且不能将这两个源文件链接在一起。谢谢,我首先通过固定头来固定,第二个通过添加*来确定。我需要这些变量作为指针来查看我的工具是否检测到从未被存储的内存位置。从initialization.BTW开始阅读,您是否可以解释更多关于“(顺便说一下,您不应该键入malloc的返回)@如果您忘记包含正确的头文件,则返回值将隐藏。这可能会引起警告,但在其他情况下仍能正常编译,但在运行程序时很可能会导致奇怪的崩溃。谢谢,我首先修复了头文件,然后添加了*。我需要这些变量作为指针来查看如果我的工具检测到自initialization.BTW以来从未读取过的内存位置,请您进一步解释一下“(顺便说一句,您不应该键入malloc的返回)?”@如果您忘记包含正确的头文件,则返回将隐藏。这可能会给您带来警告,但在其他方面仍然可以编译,但在r
int addTwo()
{
    int y = 3;
    int sum = y + y;

    return sum;
}
int main(int argc, char *argv[])
{
    int x = addTwo();

    return 0;
}