rondino rondino - 2 months ago 6x
C Question

Passing few arguments to printf as format specifier is it undefined behavior?

As I know having few format specifier than the arguments is considered as undefined behavior. Does this apply to:

printf("%1$d %1$d", 5);

PS Use of
as format specifier is an extension to the language added by POSIX.


The n$ notation is not part of standard C, but is part of POSIX. The POSIX specification for printf() supports the n$ notation to refer to arguments.

Conversions can be applied to the nth argument after the format in the argument list, rather than to the next unused argument. In this case, the conversion specifier character % (see below) is replaced by the sequence "%n$", where n is a decimal integer in the range [1,{NL_ARGMAX}], giving the position of the argument in the argument list. This feature provides for the definition of format strings that select arguments in an order appropriate to specific languages (see the EXAMPLES section).

The format can contain either numbered argument conversion specifications (that is, "%n$" and "*m$"), or unnumbered argument conversion specifications (that is, % and *), but not both. The only exception to this is that %% can be mixed with the "%n$" form. The results of mixing numbered and unnumbered argument specifications in a format string are undefined. When numbered argument specifications are used, specifying the Nth argument requires that all the leading arguments, from the first to the (N-1)th, are specified in the format string.

In format strings containing the "%n$" form of conversion specification, numbered arguments in the argument list can be referenced from the format string as many times as required.

It requires that you provide an argument for each n$, and that the format string refers to every argument 1..n. It doesn't say you have to use a different n$ each time.

The code shown is fine on POSIX systems. Since it uses a POSIX-only feature, it won't be portable to non-POSIX systems that don't have the necessary support as an extension.