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:

$ gcc --version && tail posnprintf.c && gcc -o posnprintf{,.c} && ./posnprintf
gcc (GCC) 12.4.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#define I18LL 123456789876543210LL
#define THIRD 1.0/3.0
int main(void) {
    long long   a = I18LL;
    double      b = THIRD;
    printf("expected\ta:%18lld\tb:%10.6f\n",  I18LL, THIRD);
    printf("parameters\ta:%8.8lld\tb:%10.2g\n",               a, b);
    printf("positional\ta:%2$8.8lld\tb:%1$10.2g\n",   b, a);
    printf("ignoreposn\tb:%8.8lld\ta:%10.2g\n",               b, a);
}
posnprintf.c: In function ‘main’:
posnprintf.c:12:33: warning: format ‘%lld’ expects argument of type ‘long long int’, but argument 2 has type ‘double’ [-Wformat=]
   12 |     printf("ignoreposn\tb:%8.8lld\ta:%10.2g\n",         b, a);
      |                           ~~~~~~^                       ~
      |                                 |                       |
      |                                 long long int           double
      |                           %8.8f
posnprintf.c:12:43: warning: format ‘%g’ expects argument of type ‘double’, but argument 3 has type ‘long long int’ [-Wformat=]
   12 |     printf("ignoreposn\tb:%8.8lld\ta:%10.2g\n",         b, a);
      |                                      ~~~~~^                ~
      |                                           |                |
      |                                           double           long long int
      |                                      %10.2lld
expected        a:123456789876543210    b:  0.333333
parameters      a:123456789876543210    b:      0.33
positional      a:4599676421641834218   b:  2.1e-300
ignoreposn      b:4599676419421066581   a:  2.1e-300

--
Take care. Thanks, Brian Inglis              Calgary, Alberta, Canada

La perfection est atteinte                   Perfection is achieved
non pas lorsqu'il n'y a plus rien à ajouter  not when there is no more to add
mais lorsqu'il n'y a plus rien à retirer     but when there is no more to cut
                                -- Antoine de Saint-Exupéry

--
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

Reply via email to