printf-family positional argument support

J. Johnston jjohnstn@redhat.com
Fri Aug 9 15:28:00 GMT 2002


Optional positional argument support has been added to vfprintf.c.  It is disabled
by default and can be enabled either by configuring with --enable-newlib-io-pos-args or 
compiling vfprintf.c with the -DWANT_IO_POS_ARGS flag.  It is currently enabled by
default for x86-linux.

Positional arguments are specified by specifying the argument number followed
by a dollar sign.  The first argument is 1, not 0.  Up to 32 positional arguments are supported.
The location of the main positional specifier is after any flags and before any width
specification.  You may also use positional specifiers for dynamic width or dynamic
precision which are specified after the '*' character.  Inter-mixing of positional arguments
with non-positional arguments is allowed.  Non-positional arguments consume the
argument list as normal.  If both a non-positional specifier and positional specifier
refer to the same argument, the argument is read based on the non-positional spec.
The positional specifier is then treated as a union with the value.  For example, if you
have printf("%g %1$x\n", 1.234); the %g will read in argument 1 as a double.  The
%1$d specifier results in undefined behavior (under the covers it is actually
interpreted as a union between an int and the double data).  Note that invalid format specifiers result in undefined behavior.

For example,

  printf("%d %1$x %d %2$x %3$d\n", 23, 24, 25);
  printf("%1$x %d %2$x %d %3$d\n", 23, 24, 25);
  printf("%3$x %d %2$x %d\n", 23, 24, 25, 44);
  printf("%3$x %2$x %1$d\n", 23, 24, 25);
  printf("%1$x %2$x %3$d\n", 23, 24, 25);
  printf("%3$g %2$x %1$f\n", 23.78, 24, 25.45);
  printf("%2$s %d\n", 4, "abcdefg");
  printf("%2$.*3$s %1$d\n", 1, "abcdefg", 3);
  printf("%2$.*s %1$d\n", 4, "abcdefg", 3);

outputs:

23 17 24 18 25
17 23 18 24 25
19 23 18 24
19 18 23
17 18 25
25.45 18 23.780000
abcdefg 4
abc 1
abcd 4

-- Jeff J.



More information about the Newlib mailing list