How do positional arguments like "1$" work with printf()?

Viewed 20096

By man I find

               printf("%*d", width, num);

and

               printf("%2$*1$d", width, num);

are equivalent.

But IMO the second style should be the same as:

               printf("%*d", num, width);

However via testing it seems man is right; why?

4 Answers

I agree that the man page is confusing because it explains two concepts (length modifier as positional argument) in one example, so I go to the mighty couple vi/gcc:

test.c

#include <stdio.h> 
void main(int argc, char** argv) {
    printf("%1$c\n", 'a', 'b', 'c');
    printf("%2$c\n", 'a', 'b', 'c');
    printf("%3$c\n", 'a', 'b', 'c');
    printf("%3$c %2$c %1$c\n", 'a', 'b', 'c');
}

Compiling will give warnings if not all arguments are used:

$ gcc test.c
test.c: In function ‘main’:
test.c:3:9: warning: unused arguments in $-style format [-Wformat-extra-args]
  printf("%1$d\n", 'a', 'b', 'c');
         ^~~~~~~~
test.c:4:9: warning: format argument 1 unused before used argument 2 in $-style format [-Wformat=]
  printf("%2$d\n", 'a', 'b', 'c');
         ^~~~~~~~
test.c:4:9: warning: unused arguments in $-style format [-Wformat-extra-args]
test.c:5:9: warning: format argument 1 unused before used argument 3 in $-style format [-Wformat=]
  printf("%3$d\n", 'a', 'b', 'c');
         ^~~~~~~~
test.c:5:9: warning: format argument 2 unused before used argument 3 in $-style format [-Wformat=]

But then here you see the result:

$ ./a.out
a
b
c
c b a
Related