The padding (and precision) there are part of the Int constructor (and some others) because their meaning is defined for values of those types:
For the Alpha constructor, which corresponds to %a in the format string and may delegate to any printing code, it’s not defined how those should work:
The padding value outside on the %a would somehow have to propagate inside to the %d and apply there. Maybe padding could be implemented generically (not sure if it could or it has some type-specific behavior right now), but the same criticism would apply to flags and precision as well. Those certainly cannot work for arbitrary specifiers.
But indeed, I don’t see it documented, for which specifiers flags/padding/precision work and for which they silently don’t. That’s only apparent from looking at those internals.
Fun fact: there is a -strict-formats option that rejects many invalid formats instead of silently doing something.
# Printf.printf "%20a" (fun _ -> print_int) 42;;
Error: invalid format "%20a": at character number 0,
`padding' is incompatible with 'a' in sub-format "%20a"
Benoît Vaugon and myself implemented this when we rewrote formatting support to use GADTs (Benoît’s idea). It was not enabled by default because various programs in the wild would have started failing (they contained invalid but innocuous formats and just worked), and we wanted excellent compatibility by default to sell the (large) change. Ideally this could be turned into a warning, but we never got around to doing this work. Volunteers welcome (Adding warnings is not a magic bullet because if you enable them by default, and people set errors on warnings, then you are back to breaking code again.)