我维护着一个非常古老的 C 项目(写这些的程序员早已不在了),我发现了这样的东西:
(以 //
开头的行给出包含以下行的文件的名称。)
声明:
// db/stor_procs/sp_table.c
/* Special hack prototype */
int32_t put_column_value(table_t * tab, row_t * row, u_int16_t colnum, rt_value_t * v);
// db/triggers/specials.c
/* BAD HACK */
int32_t put_column_value(table_t * tab, row_t * row, u_int16_t colnum, rt_value_t * v);
// db_sean_add_alarm/src/rt_access.c
int32_t put_column_value(struct xput_info *xptr, table_t * tab, row_t * row, u_int16_t colnum, rt_value_t * v);
// db_sean_add_alarm/stor_procs/sp_table.c
/* Special hack prototype */
int32_t put_column_value(table_t * tab, row_t * row, u_int16_t colnum, rt_value_t * v);
定义:
// db/src/rt_access.c
int32_t
put_column_value(struct xput_info *xptr, table_t * tab, row_t * row, u_int16_t colnum, rt_value_t * v){//....}
// db_sean_add_alarm/src/rt_access.c
int32_t
put_column_value(struct xput_info *xptr, table_t * tab, row_t * row, u_int16_t colnum, rt_value_t * v){//.....}
程序员从不在头文件中声明put_column_value
,而只是在.c文件中给出定义。更奇怪的是,我找不到任何 put_column_value
的定义,它将 table_t *
作为第一个参数,我是100% 确定 table_t
和 struct xput_info
是不同的类型(结构)。
但这还不是全部。最奇怪的是,我可以在其他 .c 文件中找到 put_column_value
的声明。现在我需要清理代码,但我无法理解如何处理这种 C 魔法。原始程序员在这里使用的“魔法”(hack)是什么?
整个项目有点大,我已经尽力简化问题了。如果您需要任何其他信息来解决此问题,请告诉我。
编辑
找出原因,这个项目链接到另一个库,那个库有函数原型(prototype)的定义,这就是为什么这个“魔法”(hack)可以找到实现。现在有一个大问题要解决——这个项目没有可靠的单元测试,很难为它开发一个,不测试我不能改代码,不改代码我不能做单元测试^_^。啊哈,总是维护遗留代码不是一件愉快的工作。
最佳答案
这里有几件事情需要担心。
- 将原型(prototype)放在源代码而不是头文件中的骇人听闻的编程风格。这很容易(但很乏味)修复。
- 声明和定义不匹配。鉴于您在原型(prototype)和函数的两个定义中有不同数量的参数。这些原型(prototype)似乎并没有被实际使用,因为如果它们被使用,程序就会崩溃(假设实际代码没有对它的参数做一些真正令人厌恶的事情)。因此,您可能有机会进行一些清理工作。
- 您有两个 put_column_value 的实现。大概这些是在不同的库中,不应该一起使用的。看起来这些目录之一包含带有某种警报的新版本库,但我只是从名称中猜测。
关于c - C中函数的奇怪声明和定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25442188/