c99 uint32_t (etc.) corresponding portable printf format specifiers?

Discussion in 'C Programming' started by David Mathog, Jan 26, 2011.

  1. David Mathog

    David Mathog Guest

    c99 introduced (or at least standardized) uint32_t, uint64_t etc., and
    that provides a way to write code
    so that the size of the variables remains the same on platforms where
    int, long, etc. can be different sizes. So far so good. However,
    there do not seem to be any corresponding fprintf specifiers, just the
    existing l, ll and u. and those do not have a fixed size. So in c99
    how does one write this code fragment portably?


    #include <stdlib.h>
    #include <stdio.h>
    #include <stdint.h>

    uint32_t var=1;
    fprintf(stdout,"%lu \n",var);

    That would work on a 32 bit platform, but %lu could be 8 bytes on a 64
    bit platform, rather than the intended 4 bytes.

    Thanks,

    David Mathog
    David Mathog, Jan 26, 2011
    #1
    1. Advertising

  2. David Mathog

    Ben Pfaff Guest

    David Mathog <> writes:

    > c99 introduced (or at least standardized) uint32_t, uint64_t etc., and
    > that provides a way to write code
    > so that the size of the variables remains the same on platforms where
    > int, long, etc. can be different sizes. So far so good. However,
    > there do not seem to be any corresponding fprintf specifiers, just the
    > existing l, ll and u. and those do not have a fixed size. So in c99
    > how does one write this code fragment portably?
    >
    >
    > #include <stdlib.h>
    > #include <stdio.h>
    > #include <stdint.h>
    >
    > uint32_t var=1;
    > fprintf(stdout,"%lu \n",var);


    #include <inttypes.h>
    fprintf(stdout, "%"PRIu32" \n", var);
    --
    char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
    ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
    =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
    2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
    Ben Pfaff, Jan 26, 2011
    #2
    1. Advertising

  3. David Mathog

    David Mathog Guest

    On Jan 26, 10:48 am, (Ben Pfaff) wrote:
    > #include <inttypes.h>
    > fprintf(stdout, "%"PRIu32" \n", var);


    Thanks! Which man page, if any, includes this information? It isn't
    in the fprintf page on my
    Linux systems.

    Thank you,

    David Mathog
    David Mathog, Jan 26, 2011
    #3
  4. David Mathog

    Ben Pfaff Guest

    David Mathog <> writes:

    > On Jan 26, 10:48 am, (Ben Pfaff) wrote:
    >> #include <inttypes.h>
    >> fprintf(stdout, "%"PRIu32" \n", var);

    >
    > Thanks! Which man page, if any, includes this information? It isn't
    > in the fprintf page on my
    > Linux systems.


    I doubt it appears in a manpage. One place it is documented is
    in POSIX:

    http://pubs.opengroup.org/onlinepubs/009695399/basedefs/inttypes.h.html
    --
    "I'm not here to convince idiots not to be stupid.
    They won't listen anyway."
    --Dann Corbit
    Ben Pfaff, Jan 26, 2011
    #4
  5. David Mathog <> writes:
    > On Jan 26, 10:48 am, (Ben Pfaff) wrote:
    >> #include <inttypes.h>
    >> fprintf(stdout, "%"PRIu32" \n", var);

    >
    > Thanks! Which man page, if any, includes this information? It isn't
    > in the fprintf page on my
    > Linux systems.


    I don't know which man page it's in, if any, but it's documented
    (defined, actually) in section 7.8 of the C99 standard. The latest
    almost-official draft is at
    http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf

    This won't tell you whether your implementation supports it; not
    all do, and you might not get a warning for an unsupported format.

    For simplicity, you might also consider converting to intmax_t or
    uintmax_t (var was declared as uint32_t):

    fprintf(stdout, "%ju\n", (uintmax_t)var);

    Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
    cast to intmax_t for signed variables. Personally, I find that easier
    to remember than PRIu32 and friends. Widening to uintmax_t or intmax_t
    might be more expensive, but that's hardly likely to be significant.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 26, 2011
    #5
  6. David Mathog

    Ben Pfaff Guest

    Keith Thompson <> writes:
    > For simplicity, you might also consider converting to intmax_t or
    > uintmax_t (var was declared as uint32_t):
    >
    > fprintf(stdout, "%ju\n", (uintmax_t)var);
    >
    > Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
    > cast to intmax_t for signed variables. Personally, I find that easier
    > to remember than PRIu32 and friends. Widening to uintmax_t or intmax_t
    > might be more expensive, but that's hardly likely to be significant.


    One possible consideration is that it is fairly easy to #define
    PRIu32, etc. on C89 systems that don't natively have <inttype.h>,
    but it is harder to extend a system's printf implementation to
    support the new C99 width modifiers such as 'j'.
    --
    "Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are,
    by definition, not smart enough to debug it."
    --Brian Kernighan
    Ben Pfaff, Jan 26, 2011
    #6
  7. Re: c99 uint32_t (etc.) corresponding portable printf formatspecifiers?

    Ben Pfaff wrote:
    > Keith Thompson <> writes:
    >> For simplicity, you might also consider converting to intmax_t or
    >> uintmax_t (var was declared as uint32_t):
    >>
    >> fprintf(stdout, "%ju\n", (uintmax_t)var);
    >>
    >> Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
    >> cast to intmax_t for signed variables. Personally, I find that easier
    >> to remember than PRIu32 and friends. Widening to uintmax_t or intmax_t
    >> might be more expensive, but that's hardly likely to be significant.

    >
    > One possible consideration is that it is fairly easy to #define PRIu32,
    > etc. on C89 systems that don't natively have <inttype.h>, but it is
    > harder to extend a system's printf implementation to support the new C99
    > width modifiers such as 'j'.


    Another consideration is that it's all very well saying that an
    unnecessary type widening is "hardly likely to be significant", but this
    sort of casual disregard for efficiency has a tendency to snowball, so
    that in the end a whole lot of things that individually are "hardly
    likely to be significant" accumulate into major bloat and slowdown.
    Edward Rutherford, Jan 26, 2011
    #7
  8. David Mathog

    David Mathog Guest

    On Jan 26, 11:48 am, Keith Thompson <> wrote:
    >
    > For simplicity, you might also consider converting to intmax_t or
    > uintmax_t (var was declared as uint32_t):
    >
    >     fprintf(stdout, "%ju\n", (uintmax_t)var);
    >
    > Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
    > cast to intmax_t for signed variables.


    The variables correspond to fixed width fields in binary files. I'm
    not entirely clear
    on what uintmax_t is, but my first impression was that it was "the
    biggest int that this
    platform can handle". So on a 64 bit platform wouldn't that be a 64
    bit int? Which is not
    what is needed when the file has 32 bit fields. Well, I guess it
    would work for the printf,
    but there would be problems trying to stuff data back into the 32 bit
    field from the 64 bit int.

    Thanks,

    David Mathog
    David Mathog, Jan 26, 2011
    #8
  9. David Mathog <> writes:
    > On Jan 26, 11:48 am, Keith Thompson <> wrote:
    >>
    >> For simplicity, you might also consider converting to intmax_t or
    >> uintmax_t (var was declared as uint32_t):
    >>
    >>     fprintf(stdout, "%ju\n", (uintmax_t)var);
    >>
    >> Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
    >> cast to intmax_t for signed variables.

    >
    > The variables correspond to fixed width fields in binary files. I'm
    > not entirely clear on what uintmax_t is, but my first impression was
    > that it was "the biggest int that this platform can handle".


    No, it's the biggest *unsigned integer type* supported by the C
    implementation. Remember that "int" is just one of several predefined
    integer types; it's not just a shorter way of saying "integer".

    Specifically, quoting C99 7.18.1.5:

    The following type designates a signed integer type capable of
    representing any value of any signed integer type:

    intmax_t

    The following type designates an unsigned integer type capable
    of representing any value of any unsigned integer type:

    uintmax_t

    These types are required.

    > So on a
    > 64 bit platform wouldn't that be a 64 bit int?


    It would probably be a 64-bit *integer*, though it's possible that a C
    implementation on a 64-bit platform might also support 128-bit integers.

    > Which is not what is
    > needed when the file has 32 bit fields. Well, I guess it would work
    > for the printf, but there would be problems trying to stuff data back
    > into the 32 bit field from the 64 bit int.


    No, you don't *need* to use 64 bits. The point is simply that
    converting printf arguments to int64_t or uint64_t means there's less
    stuff to keep track of; you don't have to remember that the conversion
    macros for uint32_t, uint_fast32_t, and uint least32_t are PRIu32,
    PRIuLEAST32, and PRIuFAST32, respectively. And if you change the
    definition of your variable from uint32_t to uint64_t, the printf will
    still work correctly. Converting from 32 bits to 64 probably imposes
    some runtime overhead, but it's probably swamped by the overhead
    of printf() parsing the format string and printing the output.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Jan 26, 2011
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. rh00667
    Replies:
    2
    Views:
    560
    rh00667
    Mar 2, 2007
  2. Giuseppe:G:
    Replies:
    1
    Views:
    474
    Giuseppe:G:
    Jul 12, 2008
  3. Stephan Beal
    Replies:
    13
    Views:
    5,298
    Falcon Kirtaran
    Jan 15, 2009
  4. Francois Grieu

    [C99] how to test if type uint32_t exists?

    Francois Grieu, Feb 19, 2010, in forum: C Programming
    Replies:
    10
    Views:
    4,737
    Francois Grieu
    Feb 20, 2010
  5. A. Farber
    Replies:
    11
    Views:
    296
    Jens Thoms Toerring
    Apr 4, 2009
Loading...

Share This Page