Bug in handling of "1$", "2$" in printf format

Jon Turney jon.turney@dronecode.org.uk
Sat Dec 7 16:33:48 GMT 2024


On 07/12/2024 05:26, Keith Thompson via Cygwin wrote:
> Brian Inglis wrote:
>> On 2024-12-06 19:16, Keith Thompson via Cygwin wrote:
>>> The use of "1$", "2$" et al in printf format specifiers is a
>>> POSIX-specific feature.
>>>
>>> On Cygwin (newlib) this is handled correctly in most cases, but one
>>> example I tried misbehaves.
>>> The output is correct on other implementations, including glibc and
>>> musl on Ubuntu.
>>>
>>> This C program:
>>>
>>> #include <stdio.h>
>>> int main(void) {
>>>       long long a = 123456789876543210;
>>>       double b=1.0/3;
>>>       printf("a:%2$8.8lld b:%1$10.2g\n", b, a);
>>> }
>>>
>>> should produce this output:
>>>
>>> a:123456789876543210 b:      0.33
>>>
>>> Under Cygwin (fully updated), with "gcc c.c -o c && ./c", the output is:
>>>
>>> a:140732550844138 b:  7.1e-315
>>>
>>
>> Confirmed with gcc 12.4 and minor tweaks to constant data types: printf is
>> ignoring arg positions:
> [SNIP]
> 
> It's not always ignoring arg positions. I think there's an interaction
> between the "1$" / "2$" position specification and relatively complex
> format specifiers.  The following case works correctly:
> 
> $ cat c2.c
> #include <stdio.h>
> int main(void) {
>      int a = 42;
>      double b = 1.0/3.0;
>      printf("a:%2$d b:%1$g\n", b, a);
>      printf("a:%1$d b:%2$g\n", a, b);
>      printf("a:%d b:%g\n",     a, b);
> }
> $ gcc c2.c -o c2 && ./c2
> a:42 b:0.333333
> a:42 b:0.333333
> a:42 b:0.333333
> $
> 
> (And the version of gcc shouldn't matter.  printf is implemented in
> newlib.  The code in question should be in newlib/libc/stdio/vfprintf.c.)

Not sure if this is the same/similar/different to the problem I reported 
at [1]

[1] https://sourceware.org/pipermail/newlib/2023/020374.html



More information about the Cygwin mailing list