将程序构建为库时处理静态函数
Dealing with static functions when building a program as a library
为了对我的一个程序实施单元测试,我添加了一个 makefile 规则,以便在 "make check" 为 运行 时将程序构建为静态库。我用 #ifndef TEST_LIB 和 #endif (TEST_LIB 是在构建为库时定义的。
然后我创建了一些小的 C 文件来测试该库中的一些函数。
库中的一些函数是静态声明的。
当我尝试编译测试时,您可能会猜到会产生这样的警告:
/../test/config_test.c:15:3: warning: implicit declaration of function ‘realize_home’ [-Wimplicit-function-declaration]
因为realize_home是在程序的源代码(.c文件)中静态声明的。
我尝试的一个解决方案是将#include config_rmw.c(包含静态函数)放入 .c 单元文件 (config_test)。这实际上有效并且在我编译时没有给我任何警告,即使 config_rmw.c 已经内置到库中。
我想到的另一个解决方案是
#ifndef TEST_LIB
static
#endif
void function()
{
definition
}
并将原型添加到 header,这是一个 #ifdef 语句。
#ifdef TEST_LIB
function prototype
#endif
但是这样做感觉不太对,尤其是当我继续实施更多单元测试时必须为更多功能完成时。
我最近在一本书上读到,静态函数应该放在 header 文件中。我试过了,但它只部分解决了我的问题。我结束了像这样的编译器警告:
In file included from ../../src/rmw.c:38:0:
../../src/config_rmw.h:86:1: warning: ‘realize_home’ defined but not used [-Wunused-function]
realize_home (char **str)
^~~~~~~~~~~~
我读了一些书,我有点理解为什么会这样。基本上,这意味着我会在每个 .c 文件中获得该函数的单独副本,该文件 #includes header 定义它的文件。我不需要。我静态声明一些函数的原因是因为它们只在一个文件中需要。
然后我读了一些评论,其中有人说静态函数不应该在 header 文件中定义!
所以...我一直在思考最佳方法和其他选项。我更喜欢让我的程序井井有条并练习良好的编码技能。
我只使用 script-based 方法编写了一些测试,它不需要将我的程序构建为库,但我认为使用这两种方法会有优势,具体取决于正在测试中。
更新(添加) 该程序有 20 个源文件(包括 headers)和 ~4K 行代码。
我会按照建议的去做here
我认为#including .c 文件可以用于测试。如果由于某种原因造成麻烦,pan64 建议的 "wrapper function" 方法应该是一个可以接受的折衷方案。
static void realize_home(char **)
{
implementation
}
#ifdef UNITTEST
void test_realize_home(char **v)
{
realize_home(v);
}
#endif
为了对我的一个程序实施单元测试,我添加了一个 makefile 规则,以便在 "make check" 为 运行 时将程序构建为静态库。我用 #ifndef TEST_LIB 和 #endif (TEST_LIB 是在构建为库时定义的。
然后我创建了一些小的 C 文件来测试该库中的一些函数。
库中的一些函数是静态声明的。
当我尝试编译测试时,您可能会猜到会产生这样的警告:
/../test/config_test.c:15:3: warning: implicit declaration of function ‘realize_home’ [-Wimplicit-function-declaration]
因为realize_home是在程序的源代码(.c文件)中静态声明的。
我尝试的一个解决方案是将#include config_rmw.c(包含静态函数)放入 .c 单元文件 (config_test)。这实际上有效并且在我编译时没有给我任何警告,即使 config_rmw.c 已经内置到库中。
我想到的另一个解决方案是
#ifndef TEST_LIB
static
#endif
void function()
{
definition
}
并将原型添加到 header,这是一个 #ifdef 语句。
#ifdef TEST_LIB
function prototype
#endif
但是这样做感觉不太对,尤其是当我继续实施更多单元测试时必须为更多功能完成时。
我最近在一本书上读到,静态函数应该放在 header 文件中。我试过了,但它只部分解决了我的问题。我结束了像这样的编译器警告:
In file included from ../../src/rmw.c:38:0: ../../src/config_rmw.h:86:1: warning: ‘realize_home’ defined but not used [-Wunused-function] realize_home (char **str) ^~~~~~~~~~~~
我读了一些书,我有点理解为什么会这样。基本上,这意味着我会在每个 .c 文件中获得该函数的单独副本,该文件 #includes header 定义它的文件。我不需要。我静态声明一些函数的原因是因为它们只在一个文件中需要。
然后我读了一些评论,其中有人说静态函数不应该在 header 文件中定义!
所以...我一直在思考最佳方法和其他选项。我更喜欢让我的程序井井有条并练习良好的编码技能。
我只使用 script-based 方法编写了一些测试,它不需要将我的程序构建为库,但我认为使用这两种方法会有优势,具体取决于正在测试中。
更新(添加) 该程序有 20 个源文件(包括 headers)和 ~4K 行代码。
我会按照建议的去做here
我认为#including .c 文件可以用于测试。如果由于某种原因造成麻烦,pan64 建议的 "wrapper function" 方法应该是一个可以接受的折衷方案。
static void realize_home(char **)
{
implementation
}
#ifdef UNITTEST
void test_realize_home(char **v)
{
realize_home(v);
}
#endif