gpt4 book ai didi

c - 如何删除代码中 undefined reference ?

转载 作者:行者123 更新时间:2023-11-30 20:56:08 28 4
gpt4 key购买 nike

我陷入了这个编译错误,我想知道如何调试代码。我的程序基本上有以下文件:

生成文件:

CFLAGS = -Wall -g
src = ex19.c

all: $(src)
cc $(CFLAGS) -o ex19 $(src)

ex19: object.o

clean:
rm -f ex19

对象.h:

#ifndef _object_h
#define _object_h

typedef enum{
NORTH, SOUTH, EAST, WEST
} Direction;

typedef struct {
char *description;
int (*init)(void *self);
void (*describe)(void *self);
void (*destroy)(void *self);
void *(*move)(void *self, Direction direction);
int (*attack)(void *self, int damage);
} Object;

int Object_init(void *self);
void Object_destroy(void *self);
void Object_describe(void *self);
void *Object_move(void *self, Direction direction);
int Object_attack(void *self, int damage);
void *Object_new(size_t size, Object proto, char *description);

#define NEW(T, N) Object_new(sizeof(T), T##Proto, N)
#define _(N) proto.N

#endif

对象.c:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "object.h"
#include <assert.h>

void Object_destroy(void *self) {
Object *obj = self;

if(obj) {
if(obj->description) free(obj->decription);
free(obj);
}
}

void Object_describe(void *self) {
Object *obj = self;
printf("%s.\n", obj->description);
}

int Object_init(void *self){
// do nothing really
return 1;
}

void *Object_move(void *sefl, Direction direction){
printf("You can't go that direction.\n");
return NULL;
}

int Object_attack(void *self, int damage){
printf("You can't attack that.\n");
return 0;
}

void *Object_new(size_t size, Object proto, char *description){
// setup the default functions in case they aren't set
if(!proto.init) proto.init = Object_init;
if(!proto.describe) proto.describe = Object_describe;
if(!proto.destroy) proto.destroy = Object_destroy;
if(!proto.attack) proto.attack = Object_attack;
if(!proto.move) proto.move = Object_move;

// this seems weird, but we can make a struct of one size,
// then point a different pointer at it to "cast" it
Object *el = calloc(1, size);
*el = proto;

// copy the description over
el->description = strdup(description);

// initialize it with whatever init we were given
if(!el->init(el)){
// looks like it didn't initialize properly
el->destroy(el);
return NULL;
}
else {
//all done, we made an object of any type
return el;
}
}

ex19.h:

#ifndef __ex19_h
#define __ex19_h

#include "object.h"

struct Monster {
Object proto;
int hit_points;
};

typedef struct Monster Monster;

int Monster_attack(void *self, int damage);
int Monster_init(void *self);

struct Room{
Object proto;

Monster *bad_guy;

struct Room *north;
struct Room *south;
struct Room *east;
struct Room *west;
};

typedef struct Room Room;

void *Room_move(void *self, Direction direction);
int Room_attack(void *self, int damage);
int Room_init(void *self);

struct Map{
Object proto;
Room *start;
Room *location;
};

typedef struct Map Map;

void *Map_move(void *self, Direction direction);
int Map_attack(void *self, int damage);
int Map_init(void *self);

#endif

ex19.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include "ex19.h"

int Monster_attack(void *self, int damage){
Monster *monster = self;
printf("You attack %s!\n", monster->_(description));
monster->hit_points -= damage;
if(monster->hit_points > 0) {
printf("It is still alive.\n");
return 0;
}
else{
printf("It is dead!\n");
return 1;
}
}

int Monster_init(void *self){
Monster *monster = self;
monster->hit_points = 10;
return 1;
}

Object MonsterProto = {
.init = Monster_init,
.attack = Monster_attack
};

void *Room_move(void *self, Direction direction) {
Room *room = self;
Room *next = NULL;

if(direction == NORTH && room->north) {
printf("You go north, into:\n");
next = room->north;
}
else if(direction == SOUTH && room->south){
printf("You go south, into:\n");
next = room->south;
}
else if(direction == EAST && room->east){
printf("You go east, into:\n");
next = room->east;
}
else if(direction == WEST && room->west){
printf("You go west, into:\n");
next = room->west;
}
else {
printf("You can't go that direction.");
next = NULL;
}

if(next){
next->_(describe)(next);
}
return next;
}

int Room_attack(void *self, int damage){
Room *room = self;
Monster *monster = room->bad_guy;

if(monster){
monster->_(attack)(monster, damage);
return 1;
}
else{
printf("You flail in the air at nothing. Idiot.\n");
return 0;
}
}

Object RoomProto = {
.move = Room_move,
.attack = Room_attack
};

void *Map_move(void *self, Direction direction){
Map *map = self;
Room *location = map->location;
Room *next = NULL;

next = location->_(move)(location, direction);
if(next) {
map->location = next;
}
return next;
}

int Map_attack(void *self, int damage){
Map* map = self;
Room *location = map->location;
return location->_(attack)(location, damage);
}

int Map_init(void *self){
Map *map = self;

//make some rooms for a small map
Room *hall = NEW(Room, "The great hall");
Room *throne = NEW(Room, "The throne room");
Room *arena = NEW(Room, "The arena, with the minotaur");
Room *kitchen = NEW(Room, "Kitchen, you have the knife now");

// put the bad guy in the arena
arena->bad_guy = NEW(Monster, "The evil minotaur");

// setup the map rooms
hall->north = throne;

throne->west = arena;
throne->east = kitchen;
throne->south = hall;

arena->east = throne;
kitchen->west = throne;

//start the map and the character off in the hall
map->start = hall;
map->location = hall;

return 1;
}

Object MapProto = {
.init = Map_init,
.move = Map_move,
.attack = Map_attack
};

int process_input(Map *game){
printf("\n> ");
char ch = getchar();
getchar(); // eat enter;

int damage = rand() % 4;
switch(ch){
case -1:
printf("Giving up? You such.\n");
return 0;
break;
case 'n':
game->_(move)(game, NORTH);
break;
case 's':
game->_(move)(game, SOUTH);
break;
case 'e':
game->_(move)(game, EAST);
break;
case 'w':
game->_(move)(game, WEST);
break;
case 'a':
game->_(attack)(game, damage);
break;
case 'l':
printf("You can go:\n");
if(game->location->north) printf("NORTH\n");
if(game->location->south) printf("SOUTH\n");
if(game->location->east) printf("EAST\n");
if(game->location->west) printf("WEST\n");
break;
default:
printf("What?: %d\n", ch);
}
return 1;
}

int main(int argc, char *argv[]){
//simple way to setup the randomness
srand(time(NULL));

//make our map to work with
Map *game = NEW(Map, "The hall of the Minotaur.");
printf("You enter the ");
game->location->_(describe)(game->location);
while(process_input(game)) {
}
return 0;
}

编译错误:

cc -Wall -g -o ex19 ex19.c/tmp/cccuR81O.o:在函数 Map_init' 中:
ex19/ex19.c:105: undefined reference
Object_new'ex19/ex19.c:106: 对 Object_new' 的 undefined reference
ex19/ex19.c:107: undefined reference
Object_new'ex19/ex19.c:108:对 Object_new' 的 undefined reference
ex19/ex19.c:111: undefined reference
Object_new'ex19/ex19.c:180:更多对“Object_new”的 undefined reference 如下collect2:错误:ld 返回 1 退出状态make: *** [全部] 错误 1

更新 1:有问题的线路

105  Room *hall = NEW(Room, "The great hall");
106 Room *throne = NEW(Room, "The throne room");
107 Room *arena = NEW(Room, "The arena, with the minotaur");
108 Room *kitchen = NEW(Room, "Kitchen, you have the knife now");

111 arena->bad_guy = NEW(Monster, "The evil minotaur");

最佳答案

需要更新 makefile 以将 object.o 链接到可执行文件。目前您的链接行是:

cc $(CFLAGS) -o ex19 $(src)

如果执行make(或make all),则命令将扩展为:

cc -Wall -g -o ex19 ex19.c

它尝试仅使用ex19.c生成可执行文件。

构建目标 ex19 永远不会被调用,因为 all 没有将其作为依赖项。但即使它确实如此,或者您手动编写 make ex19,仍然只会生成 object.o,您在任何链接 ex19 的地方都没有任何命令。 oobject.o 一起生成可执行文件。

您应该将 src = ex19.c 更改为 src = ex19.c object.c ,因为它们都是源文件。您可以删除 ex19: object.o 行,因为它在这里是多余的。这个 makefile 将在一行中编译和链接所有源文件,这很好。

如果您想更改 makefile 以对每个 .c 文件使用编译器的单独调用(因此链接器需要第三次调用),那么您需要进行一些更改,最好根据现有的 makefile 来建模。

关于c - 如何删除代码中 undefined reference ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27608115/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com