函数指针编译错误

Posted

技术标签:

【中文标题】函数指针编译错误【英文标题】:Function pointers compiling error 【发布时间】:2013-12-25 01:20:30 【问题描述】:

在练习自己研究函数指针的时候,出现了这样的错误

Undefined symbols for architecture x86_64:
  "_comp_employee", referenced from:
      _main in main-JEO5Je.o
  "_init_database", referenced from:
      _main in main-JEO5Je.o
  "_print_database", referenced from:
      _main in main-JEO5Je.o
  "_sort", referenced from:
      _main in main-JEO5Je.o
  "_swap_employee", referenced from:
      _main in main-JEO5Je.o
ld: symbol(s) not found for architecture x86_64

我不明白为什么会这样。我认为所有这些来源(如下)都是正确的。

这是我的代码。 employee.h 定义员工信息,定义数据库和函数。

  1 /* file employee.h */
  2 
  3 #ifndef employee_h
  4 #define employee_h
  5 
  6 typedef struct emp_struct 
  7     char name[100];
  8     int employee_no;
  9     float salary, tax_to_date;
 10  Employee;
 11 
 12 typedef Employee *Database[10];
 13 
 14 int comp_employee (int *database[], int i, int j);
 15 void swap_employee (int *data[], int i, int j);
 16 
 17 /* read in database (for this exercise fake it) */
 18 void init_database( Database employees, int no_employees );
 19 
 20 /* print out the database */
 21 void print_database ( Database people, int no_employees);
 22 
 23 #endif /* employee_h */ 

Sort.h文件是定义函数指针

  1 /* file sort.h */
  2 
  3 #ifndef sort_h
  4 #define sort_h
  5 typedef int (*comp_ptr) (int *data[], int s, int t);
  6 typedef void(*swap_ptr) (int *data[], int s, int t);
  7 
  8 void sort (int *data[], int n, comp_ptr compare, swap_ptr swap);
  9 
 10 #endif /* sort.h */

最后,main.c 将其所有标头合并到程序中。

  1 #include "sort.h"
  2 #include "employee.h"
  3 
  4 int main(int argc, char *argv[]) 
  5     const int no_employees = 10;
  6     Database people;
  7     init_database (people, no_employees);
  8     print_database(people, no_employees);
  9     sort((int**)people, no_employees, comp_employee, swap_employee);
 10     print_database(people, no_employees);
 11     return 0;
 12 

首先,我认为我的编译器混淆了<sort.h>"sort.h",这是我定义的。但是在更改标题名称后,它也会抛出相同的错误。你能给我一些关于函数指针的建议和技巧吗?

【问题讨论】:

看起来像一个链接器错误。您一定没有将这些函数的目标文件添加到链接过程中。 @FiddlingBits 我遵守了 gcc -o main main.c 这有什么问题吗? 您是否也链接了employee.csort.c 文件? (答案:不——您使用gcc -o main main.c 而不是gcc -o main main.c sort.c employee.c。)标头提供有关函数的信息,但不提供有关实现的信息。除非您包含相关的目标文件(或在命令行上指定相关的源文件),否则标题肯定并不意味着程序将正确链接。 @Sogo 你需要编译和链接其他源文件或只编译 main 然后链接其他目标文件。链接器找不到某些函数定义。 那么在编写employee.hsort.h 中提到的函数之前,您无法创建可运行的程序。您必须先提供实际功能,然后才能创建可运行的程序。更准确地说,在为从 main() 调用的每个函数、从 main() 调用的函数调用的每个函数以及从每个函数调用的每个函数提供定义之前,您无法创建可运行的程序从main() 调用的每个函数调用,依此类推。 【参考方案1】:

对于链接器抱怨的函数,您没有函数定义。将以下行添加到 `main 的底部,它将解决您的链接问题:

int main(int argc, char *argv[])

    ...


int comp_employee (int *database[], int i, int j)



void swap_employee (int *data[], int i, int j)



void init_database( Database employees, int no_employees )



void print_database ( Database people, int no_employees)



void sort (int *data[], int n, comp_ptr compare, swap_ptr swap)


这些只是存根。您必须实现它们才能使逻辑起作用。

【讨论】:

有效!非常感谢你!我以为 main 只是指函数的存在或不存在的事实,但这是错误的。 再次感谢 Fiddleling Bits 和 @JonathanLeffler !有一个美好的圣诞节! :) @Sogo 将这些定义放在自己的源文件中会更有意义。如果将函数定义放在那里有意义,请创建一个 employee.c 和 sort.c 文件。【参考方案2】:

你有几件事让我摸不着头脑,但这是我编译它的方法 -

$ cat sort.h
/* file sort.h */

#include "employee.h"

#ifndef sort_h
#define sort_h
typedef int (*comp_ptr) (Database data, int s, int t);
typedef void(*swap_ptr) (Database data, int s, int t);

void sort (Database data, int n, comp_ptr compare, swap_ptr swap);

#endif /* sort.h */
$ cat employee.h 
/* file employee.h */

#ifndef employee_h
#define employee_h

typedef struct emp_struct 
    char name[100];
    int employee_no;
    float salary, tax_to_date;
 Employee;

typedef Employee *Database[10];

int comp_employee (Database database, int i, int j);
void swap_employee (Database data, int i, int j);

/* read in database (for this exercise fake it) */
void init_database( Database employees, int no_employees );

/* print out the database */
void print_database ( Database people, int no_employees);

#endif /* employee_h */ 
$ cat main.cc
#include "sort.h"
#include "employee.h"

int comp_employee (Database database, int i, int j) 
void swap_employee (Database data, int i, int j) 
void init_database( Database employees, int no_employees ) 
void print_database ( Database people, int no_employees) 
void sort (Database data, int n, comp_ptr compare, swap_ptr swap) 

int main(int argc, char *argv[]) 
    const int no_employees = 10;
    Database people;
    init_database (people, no_employees);
    print_database(people, no_employees);
    sort(people, no_employees, comp_employee, swap_employee);
    print_database(people, no_employees);
    return 0; 

$ gcc main.cc
$ ./a.out
$

【讨论】:

是的。这篇文章中的所有人都告诉我错误来自未定义实际功能。顺便说一句,比你再次回答你的问题。圣诞快乐。 :)

以上是关于函数指针编译错误的主要内容,如果未能解决你的问题,请参考以下文章

gcc 编译错误,对象初始化解释为函数指针?

紧急求助!ARM-GCC对于函数指针调用的编译有错误?已经找到原因

明显调用的表达式前的括号必须具有(指针)函数类型 编译器错误 C2064

c中多维数组的编译器错误

编译器显示错误消息“从不强制转换的整数中生成指针”(反转数组)。我该如何解决这个问题? [关闭]

通过函数指针使用内部函数时的链接器错误