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

Était-ce utile?

La 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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top