I'm writing a conversion specifier (%b) to be able to print any unsigned integer type in binary.

Here is the full code of it: https://codereview.stackexchange.com/questions/219994/register-b-conversion-specifier

Everything seems to work right now, but there's the possibility that

sizeof(uintmax_t) > sizeof(unsigned long long)

And the same with size_t

And glibc only seems to pass info about "normal" integer types (unsigned + length modifiers or char). Is it just impossible right now to prepare for that? Maybe because there is no implementation yet where those two types are wider (AFAIK).

How does glibc handle the j and z length modifiers? Probably they just are registered as equivalents to ll, and don't have a different handling.

EDIT:

There seems to be some hint that there may exist the possibility of handling types other than the basic ones.

From <printf.h>:

/* Type of a printf specifier-arginfo function.
 INFO gives information about the format specification.
 N, ARGTYPES, *SIZE has to contain the size of the parameter for
 user-defined types, and return value are as for parse_printf_format
 except that -1 should be returned if the handler cannot handle
 this case. This allows to partially overwrite the functionality
 of existing format specifiers. */

 typedef int printf_arginfo_size_function (const struct printf_info *__info,
                     size_t __n, int *__argtypes,
                     int *__size);

See *SIZE aka int *__size

And also another hint in the deprecated old functions:

/* Old version of 'printf_arginfo_function' without a SIZE parameter. */

 typedef int printf_arginfo_function (const struct printf_info *__info,
                 size_t __n, int *__argtypes);

/* Obsolete interface similar to register_printf_specifier. It can only
 handle basic data types because the ARGINFO callback does not return
 information on the size of the user-defined type. */

 extern int register_printf_function (int __spec, printf_function __func,
                 printf_arginfo_function __arginfo)
 __THROW __attribute_deprecated__;

1 Answers

2
chux On

Is it just impossible right now to prepare for that?

Yes.

struct printf_info in not prepared for handling an implementation where there are many true integer sizes.

Instead when a j, z, t modifier is used today, it maps as none, l, ll in some fashion.

Should int128_t, int256_t, int512_t, int1024_t come out, certainly struct printf_info will evolve. It is just not known what that is today.