我正在查看代码以获取ls.c
,并注意到对xstrtoul()
的调用。我想找出这个有用的函数到底在哪里定义。这导致我进入了xstrtol.h
,它具有以下代码片段:
# define _DECLARE_XSTRTOL(name, type)
strtol_error name (const char *, char **, int, type *, const char *);
_DECLARE_XSTRTOL (xstrtol, long int)
_DECLARE_XSTRTOL (xstrtoul, unsigned long int)
_DECLARE_XSTRTOL (xstrtoimax, intmax_t)
_DECLARE_XSTRTOL (xstrtoumax, uintmax_t)
如果我理解正确,预处理器传递后生成的函数原型将是:
strtol_error xstrtoul (const char *, char **, int, unsigned long int *,
const char *);
然而,xstrtol.c
中定义的唯一相关函数是 __xstrtol()
,它具有以下签名:
strtol_error
__xstrtol (const char *s, char **ptr, int strtol_base,
__strtol_t *val, const char *valid_suffixes)
我的猜测是,不知何故,编译器每次都会映射此函数的多个实例,用另一个名称代替__xstrtol
,用另一种类型代替__strtol_t
。但我不明白这是在哪里/如何完成的。(在xstrtol.c
的顶部,这两个中的每一个只有一个#define
(。
好的,xstrtol.c
文件是真正定义函数的地方,但此源文件包含在其他源文件中,就像C++函数模板一样,以生成名称和行为略有不同的函数。
看看xstrtoul.c。它实际上包括 xstrtol.c,但定义了几个预处理器符号来修改模板函数生成:
#define __strtol strtoul
#define __strtol_t unsigned long int
#define __xstrtol xstrtoul
#define STRTOL_T_MINIMUM 0
#define STRTOL_T_MAXIMUM ULONG_MAX
#include "xstrtol.c"
将一个.c
文件包含在另一个.c
文件中是不寻常的(但并非闻所未闻(。
在C++中,有一些文件命名约定用于类似情况,其中模板定义在.tcc
文件中定义,该文件#included
在.hpp
头文件的末尾。