Is there somewhere, anywhere, where it is possible to infer what
range of values printf (the utility, not the C library function)
is expected to handle?

I can find nothing in the XCU 3.printf page, nor in XBD 5 (and also
not in XBD 12, which would be another plausible place).   There doesn't
seem to be anything about integers at all in XBD 3.

XBD 14.limits.h gives the minimum allowed value for the maximum value
of an integer (2^31 - 1) (ie: requires at least 32 bit int), but I can
find nothing that says explicitly that that applies to printf the utility.

Is there some expected minimum integer size for printf (the utility)
that is actually specified somewhere?

Further, since printf (the utility) is really just converting text
strings from one format to another, there's really no reason that there
needs to be any limit at all - there's no particular reason that integers
thousands of digits long couldn't be handled.   The standard does say that
if overflow occurs, an error message, and non-zero exit status, must
occur, but it doesn't ever say that overflow must occur.

Second question - if overflow does occur (at whatever point) what is the
value that must be printed (in addition to the error message) from a
numeric conversion.

Given a printf that uses 64 bit integers (which seems to be a very common
choice) then what should be printed from

        printf '%d\n' 0xffffc00000000000

?

(This is the example that made me think about all of this - we (NetBSD)
have been offered a patch to make the error message go away, and the
result be:
        -70368744177664
That is, treating the value as a bit pattern for the 64 bits, which then
has the sign bit set, and so prints as a negative value.

We will not be doing that.

But what should we print?  (In addition to the error).

Every shell I tested (with 2 exceptions) does:

printf '%d\n' 0xffffc00000000000
-bash: printf: warning: 0xffffc00000000000: Result too large or too small
9223372036854775807

That one, obviously, is from bash.   Note that the "every shell" for this
is not all that meaningful, many don't have printf built in, and so are
simply running the NetBSD filesystem printf utility .. so it isn't then
surprising that they all do the exact same thing as that does!   But it
is obvious that at least the NetBSD sh, bash, bosh, zsh, and ksh93 have
a builtin printf (the error messages differ...)

But that value might not be what the standard calls for (even though it
is what almost everyone does), what the standard says is:

     If an argument operand cannot be completely converted into an internal
     value appropriate to the corresponding conversion specification, a
     diagnostic message shall be written to standard error and the utility
     shall not exit with a zero exit status, but shall continue processing
     any remaining operands and shall write the value accumulated at the
     time the error was detected to standard output.

The question is, what is "the value accumulated at the time the error was
detected".

What zsh does is:

        zsh $ printf '%d\n' 0xffffc00000000000
        zsh: number truncated after 15 digits: ffffc00000000000
        1152917106560335872

which makes some sense to me, I had been thinking this might be the
correct value, before I started testing to see what was produced.
That is, after the first 15 hex digits are consumed, that is the value
(0xffffc0000000000 in decimal) and then when an attempt is made to
add one more zero, we detect the overflow, and so the value that had
been accumulated when the overflow was detected was 1152917106560335872
(when printed via %d).

The value "everybody" else prints, 9223372036854775807, is simply 2^63-1
(the max possible value) which most likely was never actually encountered
during the conversion, but is just what strtoll() returns as its value.

kre

ps: the other shell which didn't produce 9223372036854775807 was ksh93,
which actually does
        ksh93 $ printf '%d\n' 0xffffc00000000000
        -70368744177664
Sad that.   Good thing that we don't use ksh as the basis of the standard!


  • printf (the utility)... Robert Elz via austin-group-l at The Open Group

Reply via email to