Question

I was looking through the code for ls.c and noticed a call to xstrtoul(). I wanted to find out where exactly was this useful function defined. This led me to xstrtol.h, which has the following snippet:

# 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)

If I understand this correctly, the resulting function prototype after the preprocessor pass would be:

strtol_error xstrtoul (const char *, char **, int, unsigned long int *, \
                                                                   const char *);

Yet, the only related function defined in xstrtol.c is __xstrtol(), which has the following signature:

strtol_error
__xstrtol (const char *s, char **ptr, int strtol_base,
           __strtol_t *val, const char *valid_suffixes)

My guess is that somehow, the compiler is mapping multiple instances of this function each time with another name substituted for __xstrtol and another type for __strtol_t. But I don't understand where/how this is done. (There is only a #define for each of those two at the top of xstrtol.c).

Was it helpful?

Solution

OK, the xstrtol.c file is where the function is really defined, but this source file is included into other source files, acting like a C++ function template, to generate functions with slightly different names and behavior.

Look at xstrtoul.c. It actually includes xstrtol.c but defines several preprocessor symbols to modify the template function generation:

#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"

It's unusual (but not unheard-of) to include a .c file into another .c file.

In C++, there are file naming conventions used for the similar situation where template definitions are defined in a .tcc file which is #included at the end of a .hpp header file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top