• on printf's "%ju"

    From Meredith Montgomery@21:1/5 to All on Sat Nov 27 13:15:43 2021
    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    --8<---------------cut here---------------start------------->8---
    EXAMPLES
    Getting the Current Time
    The following example uses the time() function to calculate the time
    elapsed, in seconds, since the Epoch, localtime() to convert that value
    to a broken-down time, and asctime() to convert the broken-down time
    values into a printable string.

    #include <stdio.h>
    #include <time.h>

    int main(void)
    {
    time_t result;

    result = time(NULL);
    printf("%s%ju secs since the Epoch\n",
    asctime(localtime(&result)),
    (uintmax_t)result);
    return(0);
    }

    This example writes the current time to stdout in a form like this:

    Wed Jun 26 10:32:15 1996
    835810335 secs since the Epoch
    --8<---------------cut here---------------end--------------->8---

    The type there is uintmax_t, perhaps defined by inttypes.h. When I look
    at the manual for inttypes.h, it suggests I should use constants such as PRIxMAX. Under msys2-64, the constant PRIxMAX expands to %ld. But my
    printf under MinGW-64 does understand %ju just fine. Where is the
    manual I'm missing? Thank you!

    (*) The source of the information

    I looked at ``man 3p time'' under msys2-64. These manual pages are
    installed with the package man-pages-posix. The package itself reports
    that it has something to do with https://www.kernel.org/doc/man-pages.

    --8<---------------cut here---------------start------------->8---
    %pacman -Si man-pages-posix
    Repository : msys
    Name : man-pages-posix
    Version : 2017_a-1
    Description : POSIX Manual Pages
    Architecture : any
    URL : https://www.kernel.org/doc/man-pages
    Licenses : custom:posix
    Groups : None
    Provides : None
    Depends On : man
    Optional Deps : None
    Conflicts With : None
    Replaces : None
    Download Size : 2.58 MiB
    Installed Size : 2.58 MiB
    Packager : CI (msys2-autobuild/310a1fa4/1493542190)
    Build Date : Tue Nov 23 03:25:13 2021
    Validated By : MD5 Sum SHA-256 Sum Signature
    --8<---------------cut here---------------end--------------->8---

    Looking it up, I find

    https://man7.org/linux/man-pages/man2/time.2.html

    but the example is not there.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Richard Kettlewell@21:1/5 to Lew Pitcher on Sat Nov 27 16:42:54 2021
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
    On Sat, 27 Nov 2021 13:15:43 -0300, Meredith Montgomery wrote:

    Here's an example of how to use time(). It uses %ju in printf.
    Where can I find a definition of these %-specifiers?

    In the printf(2) manpage ("man 2 printf") under "Length Modifier" (for
    the "j" flag) and "Conversion specifiers" (for the "u" flag)

    man 3 printf.

    https://man7.org/linux/man-pages/man3/printf.3.html

    --
    https://www.greenend.org.uk/rjk/

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lew Pitcher@21:1/5 to Richard Kettlewell on Sat Nov 27 16:45:32 2021
    On Sat, 27 Nov 2021 16:42:54 +0000, Richard Kettlewell wrote:

    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
    On Sat, 27 Nov 2021 13:15:43 -0300, Meredith Montgomery wrote:

    Here's an example of how to use time(). It uses %ju in printf.
    Where can I find a definition of these %-specifiers?

    In the printf(2) manpage ("man 2 printf") under "Length Modifier" (for
    the "j" flag) and "Conversion specifiers" (for the "u" flag)

    man 3 printf.

    https://man7.org/linux/man-pages/man3/printf.3.html

    Fsck! I thought I got the right manual section, but I flubbed it.
    Sorry.


    --
    Lew Pitcher
    "In Skills, We Trust"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lew Pitcher@21:1/5 to Meredith Montgomery on Sat Nov 27 16:27:31 2021
    On Sat, 27 Nov 2021 13:15:43 -0300, Meredith Montgomery wrote:

    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    In the printf(2) manpage ("man 2 printf") under "Length Modifier"
    (for the "j" flag) and "Conversion specifiers" (for the "u" flag)

    [snip]

    --
    Lew Pitcher
    "In Skills, We Trust"

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Keith Thompson@21:1/5 to Meredith Montgomery on Sat Nov 27 13:32:37 2021
    Meredith Montgomery <mmontgomery@levado.to> writes:
    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    --8<---------------cut here---------------start------------->8---
    EXAMPLES
    Getting the Current Time
    The following example uses the time() function to calculate the time
    elapsed, in seconds, since the Epoch, localtime() to convert that value
    to a broken-down time, and asctime() to convert the broken-down time
    values into a printable string.

    #include <stdio.h>
    #include <time.h>

    int main(void)
    {
    time_t result;

    result = time(NULL);
    printf("%s%ju secs since the Epoch\n",
    asctime(localtime(&result)),
    (uintmax_t)result);
    return(0);
    }

    This example writes the current time to stdout in a form like this:

    Wed Jun 26 10:32:15 1996
    835810335 secs since the Epoch
    --8<---------------cut here---------------end--------------->8---


    The type there is uintmax_t, perhaps defined by inttypes.h. When I look
    at the manual for inttypes.h, it suggests I should use constants such as PRIxMAX. Under msys2-64, the constant PRIxMAX expands to %ld. But my
    printf under MinGW-64 does understand %ju just fine. Where is the
    manual I'm missing? Thank you!

    (*) The source of the information

    I looked at ``man 3p time'' under msys2-64. These manual pages are
    installed with the package man-pages-posix. The package itself reports
    that it has something to do with https://www.kernel.org/doc/man-pages.

    --8<---------------cut here---------------start------------->8---
    %pacman -Si man-pages-posix
    Repository : msys
    Name : man-pages-posix
    Version : 2017_a-1
    Description : POSIX Manual Pages
    Architecture : any
    URL : https://www.kernel.org/doc/man-pages
    Licenses : custom:posix
    Groups : None
    Provides : None
    Depends On : man
    Optional Deps : None
    Conflicts With : None
    Replaces : None
    Download Size : 2.58 MiB
    Installed Size : 2.58 MiB
    Packager : CI (msys2-autobuild/310a1fa4/1493542190)
    Build Date : Tue Nov 23 03:25:13 2021
    Validated By : MD5 Sum SHA-256 Sum Signature
    --8<---------------cut here---------------end--------------->8---

    Looking it up, I find

    https://man7.org/linux/man-pages/man2/time.2.html

    but the example is not there.

    In addition to the man pages others have cited, the canonical definition
    is in the ISO C standard.

    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf is a public
    draft of the 2011 edition of the ISO C standard. I'm not aware of any
    relevant changes in later editions.

    Section 7.21.6.1 defines fprintf (printf is defined in terms of
    fprintf), including the 'j' length modifier and the 'u' and 'd'
    conversion specifiers.

    7.27.2.4 defines the time() function.

    7.20 defines the <stdint.h> header, which defines uintmax_t. If you
    have an unsigned integer for which you don't know the correct printf
    format string, you can convert to uintmax_t (which is guaranteed not to
    lose information) and print using "%ju".

    <inttypes.h> includes <stdint.h> and declares several functions and
    macros like PRIxMAX. (<stdint.h> is required for all implementations; <inttypes.h> is required only for hosted implementations. Freestanding implementations needn't support any library functions.)

    You can't assume that time_t is equivalent to any specific integer type,
    or (as the sample code above does) that it's unsigned (it's usually
    signed), or even that it's an integer type (POSIX requires it to be an
    integer type; C doesn't).

    Since this is comp.unix.programmer, I suppose you can assume POSIX, but
    be aware of what assumptions you're making.

    I would have converted to intmax_t and used "%jd" rather than "%ju",
    because time_t is *usually* a signed integer type. If I wanted to be
    painfully portable, I'd do something like this:

    #include <time.h>
    #include <stdint.h>
    #include <stdio.h>
    int main(void) {
    const time_t now = time(NULL);
    if ((time_t)1 / 2 > 0) {
    // time_t is a floating-point type
    printf("%Lf\n", (long double)now);
    }
    else if ((time_t)-1 < 0) {
    // time_t is an unsigned integer type
    printf("%ju\n", (uintmax_t)now);
    }
    else {
    // time_t is a signed integer type
    printf("%jd\n", (intmax_t)now);
    }
    }

    Note that time() returns (time_t)-1 if the calendar time is not
    available. If time_t is an unsigned type, that will give you the
    maximum value of that type, perhaps 18446744073709551615
    (0xffffffffffffffff).

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    Working, but not speaking, for Philips
    void Void(void) { Void(); } /* The recursive call of the void */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From James Kuyper@21:1/5 to Meredith Montgomery on Sat Nov 27 16:18:15 2021
    On 11/27/21 11:15 AM, Meredith Montgomery wrote:
    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    --8<---------------cut here---------------start------------->8---
    EXAMPLES
    Getting the Current Time
    The following example uses the time() function to calculate the time
    elapsed, in seconds, since the Epoch, localtime() to convert that value
    to a broken-down time, and asctime() to convert the broken-down time
    values into a printable string.

    #include <stdio.h>
    #include <time.h>

    int main(void)
    {
    time_t result;

    result = time(NULL);
    printf("%s%ju secs since the Epoch\n",
    asctime(localtime(&result)),
    (uintmax_t)result);
    return(0);
    }

    While the C standard allows time_t to be any real type, Unix requires it
    to be an integer type. That's the only thing you can portably assume
    about it; in particular, you don't know whether or not it's a signed
    type. However, that's (barely) enough to print it out reliably. You can
    safely convert a value of any signed integer type to intmax_t without
    change of value, and you can safely convert a value of any unsigned
    integer type to uintmax_t. However, if you're willing to accept a change
    of value, a value of any integer type can be safely converted to
    uintmax_t, which is what they're relying upon.

    This example writes the current time to stdout in a form like this:

    Wed Jun 26 10:32:15 1996
    835810335 secs since the Epoch
    --8<---------------cut here---------------end--------------->8---

    The type there is uintmax_t, perhaps defined by inttypes.h. When I look
    at the manual for inttypes.h, it suggests I should use constants such as PRIxMAX. Under msys2-64, the constant PRIxMAX expands to %ld. But my
    printf under MinGW-64 does understand %ju just fine. Where is the
    manual I'm missing? Thank you!

    The PRI* macros were designed to solve the problem of not knowing which
    length modifier to use when working with the size-named types, which
    could be typedefs for different standard types on different
    implementations of C. They also cover a couple of other integer
    typedefs: [u]intmax_t and ptrdiff_t.

    But C99, which was the version that introduced the size-named types,
    also introduced new length modifiers: 'j' for [u]intmax_t, 'z' for
    size_t, and 't;' for ptrdiff_t. The 'j' and 't' length modifiers render
    the corresponding inttypes macros unnecessary - I've no idea why they
    added both - the C99 Rationale document is no help - it doesn't mention
    either change. "%ju" is much simpler and easier to use than "%" PRIuMAX.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Keith Thompson@21:1/5 to Meredith Montgomery on Tue Nov 30 18:09:57 2021
    Meredith Montgomery <mmontgomery@levado.to> writes:
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
    On Sat, 27 Nov 2021 13:15:43 -0300, Meredith Montgomery wrote:
    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    In the printf(2) manpage ("man 2 printf") under "Length Modifier"
    (for the "j" flag) and "Conversion specifiers" (for the "u" flag)

    Thank you. I found in the manuals in GNU systems, but my printf is in section 3. Section 2 is usually for system calls, I guess. Why is your printf in section 2? What system are you using?

    It isn't. I speak a very obscure dialect of English in which the number
    three is spelled "2". Yeah, that's it.

    --
    Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
    Working, but not speaking, for Philips
    void Void(void) { Void(); } /* The recursive call of the void */

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Meredith Montgomery@21:1/5 to Meredith Montgomery on Tue Nov 30 22:16:29 2021
    Meredith Montgomery <mmontgomery@levado.to> writes:

    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    On Sat, 27 Nov 2021 13:15:43 -0300, Meredith Montgomery wrote:

    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    In the printf(2) manpage ("man 2 printf") under "Length Modifier"
    (for the "j" flag) and "Conversion specifiers" (for the "u" flag)

    Thank you. I found in the manuals in GNU systems, but my printf is in section 3. Section 2 is usually for system calls, I guess. Why is your printf in section 2? What system are you using?

    I guess you got the section wrong --- saw later in the thread.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Meredith Montgomery@21:1/5 to James Kuyper on Tue Nov 30 22:21:26 2021
    James Kuyper <jameskuyper@alumni.caltech.edu> writes:

    On 11/27/21 11:15 AM, Meredith Montgomery wrote:
    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    --8<---------------cut here---------------start------------->8---
    EXAMPLES
    Getting the Current Time
    The following example uses the time() function to calculate the time
    elapsed, in seconds, since the Epoch, localtime() to convert that value
    to a broken-down time, and asctime() to convert the broken-down time
    values into a printable string.

    #include <stdio.h>
    #include <time.h>

    int main(void)
    {
    time_t result;

    result = time(NULL);
    printf("%s%ju secs since the Epoch\n",
    asctime(localtime(&result)),
    (uintmax_t)result);
    return(0);
    }

    While the C standard allows time_t to be any real type, Unix requires it
    to be an integer type. That's the only thing you can portably assume
    about it; in particular, you don't know whether or not it's a signed
    type. However, that's (barely) enough to print it out reliably. You can safely convert a value of any signed integer type to intmax_t without
    change of value, and you can safely convert a value of any unsigned
    integer type to uintmax_t. However, if you're willing to accept a change
    of value, a value of any integer type can be safely converted to
    uintmax_t, which is what they're relying upon.

    Very nice information. Thanks a lot.

    This example writes the current time to stdout in a form like this: >>
    Wed Jun 26 10:32:15 1996
    835810335 secs since the Epoch
    --8<---------------cut here---------------end--------------->8---

    The type there is uintmax_t, perhaps defined by inttypes.h. When I look
    at the manual for inttypes.h, it suggests I should use constants such as
    PRIxMAX. Under msys2-64, the constant PRIxMAX expands to %ld. But my
    printf under MinGW-64 does understand %ju just fine. Where is the
    manual I'm missing? Thank you!

    The PRI* macros were designed to solve the problem of not knowing which length modifier to use when working with the size-named types, which
    could be typedefs for different standard types on different
    implementations of C. They also cover a couple of other integer
    typedefs: [u]intmax_t and ptrdiff_t.

    But C99, which was the version that introduced the size-named types,
    also introduced new length modifiers: 'j' for [u]intmax_t, 'z' for
    size_t, and 't;' for ptrdiff_t. The 'j' and 't' length modifiers render
    the corresponding inttypes macros unnecessary - I've no idea why they
    added both - the C99 Rationale document is no help - it doesn't mention either change. "%ju" is much simpler and easier to use than "%" PRIuMAX.

    Special thanks for the historical point of view. I side with you ---
    "%ju" much simpler than "%" PRIuMAX.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Meredith Montgomery@21:1/5 to Lew Pitcher on Tue Nov 30 22:15:46 2021
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:

    On Sat, 27 Nov 2021 13:15:43 -0300, Meredith Montgomery wrote:

    Here's an example of how to use time(). It uses %ju in printf. Where
    can I find a definition of these %-specifiers?

    In the printf(2) manpage ("man 2 printf") under "Length Modifier"
    (for the "j" flag) and "Conversion specifiers" (for the "u" flag)

    Thank you. I found in the manuals in GNU systems, but my printf is in
    section 3. Section 2 is usually for system calls, I guess. Why is your
    printf in section 2? What system are you using?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Meredith Montgomery@21:1/5 to Keith Thompson on Sat Dec 4 20:57:19 2021
    Keith Thompson <Keith.S.Thompson+u@gmail.com> writes:

    Meredith Montgomery <mmontgomery@levado.to> writes:
    Lew Pitcher <lew.pitcher@digitalfreehold.ca> writes:
    On Sat, 27 Nov 2021 13:15:43 -0300, Meredith Montgomery wrote:
    Here's an example of how to use time(). It uses %ju in printf. Where >>>> can I find a definition of these %-specifiers?

    In the printf(2) manpage ("man 2 printf") under "Length Modifier"
    (for the "j" flag) and "Conversion specifiers" (for the "u" flag)

    Thank you. I found in the manuals in GNU systems, but my printf is in
    section 3. Section 2 is usually for system calls, I guess. Why is your
    printf in section 2? What system are you using?

    It isn't. I speak a very obscure dialect of English in which the number three is spelled "2". Yeah, that's it.

    Lol! That actually works. But it certainly violates the principle of
    least surprise. :-)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)