Re: Anyone object to the following change in libc?

From: Daniel Eischen <eischen_at_vigrid.com>
Date: Tue, 28 Oct 2003 09:33:25 -0500 (EST)
On Tue, 28 Oct 2003, Harti Brandt wrote:

> 
> (Cc set to current).
> 
> On Tue, 28 Oct 2003, Jordan K Hubbard wrote:
> 
> JKH>Back in the pre-panther timeframe, we received the following bug report:
> JKH>
> JKH>Earlier versions of Mac OS X (e.g., 10.2.6) return a value of -1 with
> JKH>the following program:
> JKH>
> JKH>#include <stdlib.h>
> JKH>
> JKH>main()
> JKH>{   int ret, x;
> JKH>     ret = sscanf ("123", "%*d%d", &x);
> JKH>     printf("ret is %d\n", ret);
> JKH>}
> JKH>
> JKH>On Panther, the return value is zero. It affects packages like GMP,
> JKH>whose automated test sequence assumes that "-1" is the proper return
> JKH>value.
> JKH>
> JKH>A little investigation revealed that FreeBSD had changed vfscanf()
> JKH>about 6 years ago, but it was the only "Unix" to do so and everyone
> JKH>else has stuck with the more traditional behavior of returning an error
> JKH>in this case.  We've done some investigation and consulted SUSv3, but
> JKH>it's unfortunately vague on what the "proper" behavior should be so it
> JKH>seems that it's been left to the various implementations to decide for
> JKH>themselves what constitutes correct behavior.  Given the fact that
> JKH>FreeBSD appears to be the odd-man out, we plan to revert back to the
> JKH>10.2.6 behavior for vfscanf() in 10.4, but it seems a pity to have
> JKH>FreeBSD diverge here (not just from Mac OS X past and future but from
> JKH>Linux and Solaris) in ways that break known 3rd-party software and for
> JKH>reasons which remain obscure.
> JKH>
> JKH>So, two questions:
> JKH>
> JKH>1. Are the reasons not as obscure as I think?  I'd welcome an
> JKH>explanation as to why this was done.
> 
> I think ISO-C is pretty clear here. Basically three things happen when
> the scanf() finds a format specifier: it matches the input string
> according to the format specifier, if that match is not empty it converts
> the value to the corresponding type and, if assignment suppression was
> not specified it assigns the value.
> 
> When applying "%*d%d" to the string "123" the first 'd' format matches
> the string "123" and the conversion yields the number 123. This is then
> thrown away because assignment is suppressed. The next format specified
> finds an EOF condition on the stream so this counts as an input error
> according to paragraph 9, last sentence of 7.19.6.2.
> 
> According to to paragraph 18 ("The fscanf function returns the value of
> the macro EOF if an input failure occurs before any conversion. Otherwise,
> the function returns the number of input items assigned, which can be
> fewer than provided for, or even zero, in the event of an early matching
> failure.") the function returns 0, because there was a succesful
> conversion but no assignment.
> 
> I just had a look at the v7 implementation. In this implementation a
> suppressed assignment is not counted as a match even if the
> match was successful. This explains the return of -1 if the first
> not-suppressed conversion failes.
> 
> I think changing current behaviour would be a regression with regard to
> ISO-C (and Posix).

I agree, and to add a little snippet of POSIX:

  RETURN VALUE

    Upon successful completion, these functions shall return the
    number of successfully matched and assigned input items; this
    number can be zero in the event of an early matching failure.
    If the input ends before the first matching failure or
    conversion, EOF shall be returned. If a read error occurs, the
    error indicator for the stream is set, EOF shall be returned,
    and errno shall be set to indicate the error.

There is no matching failure, but there is a conversion.  I think
"%*d" just counts as an assignment suppression but does not suppress
the fact that a conversion occurred.

On the other hand, Solaris 8 does seem to return -1...

-- 
Dan Eischen
Received on Tue Oct 28 2003 - 05:33:35 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:37:26 UTC