函数未定义,即使它位于不同的.h文件中

时间:2015-07-16 20:22:45

标签: c makefile

我收到编译错误,说某些函数未定义。所有这些函数都在名为auxilarity.h的文件中定义,并在auxilarity.c

中实现

我似乎无法找到我所缺少的东西。

这是我的makefile:

assembly: main.o assembler.o hashtable.o  auxilarity.o
    gcc -g -ansi -Wall -pedantic main.o assembler.o hashtable.o -o assembly

auxilarity.o: auxilarity.c  auxilarity.h
    gcc -c -ansi -Wall -pedantic auxilarity.c -o auxilarity.o

main.o: main.c assembly.h hash.h
    gcc -c -ansi -Wall -pedantic main.c -o main.o

assembler.o: assembler.c assembly.h auxilarity.h
    gcc -c -ansi -Wall -pedantic assembler.c -o assembler.o

hashtable.o: hashtable.c auxilarity.h hash.h
    gcc -c -ansi -Wall -pedantic hashtable.c -o hashtable.o

以及相关部分:

assembler.c:

#include "assembly.h"
#include "hash.h"
#include "auxilarity.h"

... some code ...

int isArgValid(char *s) {
    char *ns;
    ns = cleanstr(s); /* <-- compiler yells on cleanstr as undefined*/

    if(ns[0] == 'r' && ns[1] >= '0' && ns[1] <= '8' && strlen(ns) == 2) {
        printf("argument %s is a register", s);
        return ARG_REGISTER;
    }
    return 1;

}

...  some code  ...

auxilarity.h:

#ifndef AUXILARITY_H_
#define AUXILARITY_H_

char *cleanstr(char *s);
char *_strdup(char *s);

#endif /* AUXILARITY_H_ */

这是 auxilarity.c

#include <string.h>
#include <stdlib.h>
#include "auxilarity.h"

/*remove leading and following spaces*/
char *cleanstr(char *s) {
        int i, j, k;
        char *copy;
        for(i = 0; s[i] == ' ' && s[i] == '\t'; i++)
            ;
        for(k = i; s[i] != '\0'; k++) {
            if(s[i] != ' ' && s[i] != '\t')
                j =k;
        }

        copy = (char *) malloc(j-i);
        memcpy(copy, s, j-i);
        return copy;
}

char *_strdup(char *s) {
    char *p;

    p = (char *) malloc(strlen(s) + 1);
    if (p != NULL)
        strcpy(p, s);
    return p;
}

这是我收到的确切错误消息(这是法语,抱歉):

hashtable.c:48:9: warning: implicit declaration of function ‘free’ [-Wimplicit-function-declaration]
         free((void *) np->defn); /*free previous defn */
         ^
hashtable.c:48:9: warning: incompatible implicit declaration of built-in function ‘free’ [enabled by default]
gcc -c -ansi -Wall -pedantic auxilarity.c -o auxilarity.o
gcc -g -ansi -Wall -pedantic main.o assembler.o hashtable.o -o assembly
assembler.o: dans la fonction « parseInstruction »:
assembler.c:(.text+0x15): référence indéfinie vers « _strdup »
assembler.o: dans la fonction « isArgValid »:
assembler.c:(.text+0x240): référence indéfinie vers « cleanstr »
hashtable.o: dans la fonction « put »:
hashtable.c:(.text+0x123): référence indéfinie vers « _strdup »
collect2: error: ld returned 1 exit status
make: *** [assembly] Erreur 1

我全神贯注地找不到我做错了什么

(尽管我已经包含了相关的.h文件,但我也为内置函数malloc获得了一些隐式函数定义警告)

2 个答案:

答案 0 :(得分:1)

在标题文件中,您声明这些函数。它们在标题中不是定义(并且不应该在标题中定义,除非它们是内联函数,需要谨慎和C99,-ansi排除)。 编译器明确告诉。

您必须定义该功能(例如,在其他源文件中)。因此像

.h文件中的声明(已完成)

char *cleanstr(char *s);

在.c文件中定义

char *cleanstr(char *s){ 
    // some code...
}

答案 1 :(得分:1)

你有问题:

assembly: main.o assembler.o hashtable.o  auxilarity.o
    gcc -g -ansi -Wall -pedantic main.o assembler.o hashtable.o -o assembly

您将auxilarity.o列为依赖项,但不要在命令行中将其链接。

您应该更多地使用宏:

OBJECT = main.o assembler.o hashtable.o auxilarity.o

assembly: ${OBJECT}
    gcc -g -ansi -Wall -pedantic ${OBJECT} -o $@

使用宏可确保一致性。 对于编译器及其大多数选项,您应该使用更多的宏。但这至少可以确保一致性。

实际上,所有重复的编译行都存在问题。 make具有编译代码的内置规则;使用它们。

CFLAGS  = -g -ansi -Wall -pedantic -Werror
OBJECT  = main.o assembler.o hashtable.o auxilarity.o
LDFLAGS =
LDLIBS  =

assembly: ${OBJECT}
    ${CC} ${CFLAGS} ${OBJECT} -o $@ ${LDFLAGS} ${LDLIBS}

auxilarity.o: auxilarity.c  auxilarity.h
main.o:       main.c assembly.h hash.h
assembler.o:  assembler.c assembly.h auxilarity.h
hashtable.o:  hashtable.c auxilarity.h hash.h

即使在列出依赖关系时,make也会推断main.o取决于main.c,因此您不必列出相关内容(尽管没有任何伤害)如果你这样做,完整性表明它是好的)。但是,您确实需要列出标题。

关于undeclared function警告,请确保在文件中包含<stdlib.h>。由于您说assembler.h包含<stdlib.h>hashtable.c不包含assembler.h,因此您需要将#include <stdlib.h>加入hashtable.c

通常,您应该包括您使用的内容(IWYU)。同样,标题应该是自包含的。关于这个主题有很多关于SO的问题,所以我不会为他们重复答案。