Looking for tips for portable printf() specifiers for signed ints ofvarying sizes

Discussion in 'C Programming' started by Stephan Beal, Jan 11, 2009.

  1. Stephan Beal

    Stephan Beal Guest

    Hi, all!

    i am working on a piece of software where the size of one of the core
    int types is configurable to be 8, 16, 32, or 64 bits (uint8_t ..
    uint64_t). That's all working fine and well, but i've got a slight
    problem when it comes to outputing them: my printf() specifiers have
    to be different depending on the exact width of the type. (Granted,
    all of that is debugging code, and doesn't directly affect the
    library, but it annoys the hell out of me nonetheless.)

    e.g.:

    typedef uint32_t id_type;
    ....
    id_type x = 34;
    printf("%u\n", x );

    that'll work, it seems, as long as i'm on a 32-bit platform. If i
    reconfigure the software to use:

    typedef uint64_t id_type;

    then i've got a problem: i've got to change the printf() to use to
    %llu or %lu (depends on the bitness of the platform, apparently) to
    avoid a warning from the compiler (a reasonable warning, IMO, and not
    one i want to ignore).

    Is there a canon solution to dealing with this?

    A related point: what are the proper printf specifiers to use for each
    uint type (8-64 bits)? As best as i can determine they are:

    uint8_t: %hhu
    uint16_t: %hu
    uint32_t: %u
    uint64_t: %llu or %lu?

    :-?

    i seem to remember reading that %hhX and %llX are GNU-specific (or not
    standard), but i can't find anything to back that up with at the
    moment.

    Are there *standard* specifiers i can reliably use for each of those
    types?
     
    Stephan Beal, Jan 11, 2009
    #1
    1. Advertising

  2. Re: Looking for tips for portable printf() specifiers for signedints of varying sizes

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Stephan Beal wrote:
    > Hi, all!
    >
    > i am working on a piece of software where the size of one of the core
    > int types is configurable to be 8, 16, 32, or 64 bits (uint8_t ..
    > uint64_t). That's all working fine and well, but i've got a slight
    > problem when it comes to outputing them: my printf() specifiers have
    > to be different depending on the exact width of the type. (Granted,
    > all of that is debugging code, and doesn't directly affect the
    > library, but it annoys the hell out of me nonetheless.)
    >
    > e.g.:
    >
    > typedef uint32_t id_type;
    > ...
    > id_type x = 34;
    > printf("%u\n", x );
    >
    > that'll work, it seems, as long as i'm on a 32-bit platform. If i
    > reconfigure the software to use:
    >
    > typedef uint64_t id_type;
    >
    > then i've got a problem: i've got to change the printf() to use to
    > %llu or %lu (depends on the bitness of the platform, apparently) to
    > avoid a warning from the compiler (a reasonable warning, IMO, and not
    > one i want to ignore).
    >
    > Is there a canon solution to dealing with this?
    >
    > A related point: what are the proper printf specifiers to use for each
    > uint type (8-64 bits)? As best as i can determine they are:
    >
    > uint8_t: %hhu
    > uint16_t: %hu
    > uint32_t: %u
    > uint64_t: %llu or %lu?
    >
    > :-?
    >
    > i seem to remember reading that %hhX and %llX are GNU-specific (or not
    > standard), but i can't find anything to back that up with at the
    > moment.
    >
    > Are there *standard* specifiers i can reliably use for each of those
    > types?


    %llu (and %Lu, which is equivalent when using gnu) aren't standard
    because long long unsigned int is not a standard type, if memory serves.

    Just to clarify, what do you mean by core int types? Also, do you know
    how they are configured? If it is a macro, I don't know if you can do
    too much. If it is configured at runtime, you would need to use runtime
    type identification to generate your format strings.

    - --
    - --Falcon Darkstar Kirtaran
    - --
    - --OpenPGP: (7902:4457) 9282:A431

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.9 (GNU/Linux)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iQIcBAEBAgAGBQJJam0OAAoJEKmxP9YxEE4rWoYQAMMLkf0E567iJKsLomPxgLcT
    BZuMPrZ+v09pqFoeT8t/NQ57v3+wInj96baRM9HrdMc+KRVdUoouIc5kT/GOh69U
    ddVPOXLMa4ox6p4PRAL2B5x7NkXfzKbJJhy+8qyfluDFiaU5Gd2OxR81Ip7nd2nE
    +vu46QadGgMlE7b6aR64/34LyycZA2wrbtGi0u6WAgMEV4o4c9onQgLbOC7n6GZ3
    JUUMLfhcTOmHXbdcSUP6OWmku2WWHyBtNjtuwk9xZF6ibfzOgpKUnkpnQaUofvG5
    eI1EOcssmnDn+exU+yIhoiYVQas0zE4SCRAzwVCDZi36pJiDqGUvBZAbAuIFLQbY
    p52qxdaadId4v21Swwyiq+SO70WZyyyuJhwinT2HeTfLCZhI6FTaWpbDt0Q+3cUP
    Xiwag8E0B++bkcK8i5iDVdPmNUpl60ND3qipMy4zMpzfjeYZIOnnhccuogaj+F9x
    4Cmr+XjNh+8JgTN45V2yfEiQd+AxCFpo2k9xhzu6eGEA15Lkr9QVVN/cp0gDtpSZ
    RHLAzlPy2V/9YpylBxPUsAefMTL+CeGNP/3GZfIMXJhGrsfeSWnDTsX9WRq1Z8al
    gRytZFlRqFPqMgSH9rTpFZbRsOxA5oKOhTRiKH0n3JaZaIZNZ8dtVcdElJEhFwlK
    tKvUscsn7z+BVJpMAuNb
    =chMA
    -----END PGP SIGNATURE-----
     
    Falcon Kirtaran, Jan 11, 2009
    #2
    1. Advertising

  3. Re: Looking for tips for portable printf() specifiers for signedints ofvarying sizes

    Stephan Beal wrote:
    > Hi, all!
    >
    > i am working on a piece of software where the size of one of the core
    > int types is configurable to be 8, 16, 32, or 64 bits (uint8_t ..
    > uint64_t). That's all working fine and well, but i've got a slight
    > problem when it comes to outputing them: my printf() specifiers have to
    > be different depending on the exact width of the type. (Granted, all of
    > that is debugging code, and doesn't directly affect the library, but it
    > annoys the hell out of me nonetheless.)


    Take a look at <inttypes.h>.

    > e.g.:
    >
    > typedef uint32_t id_type;
    > ...
    > id_type x = 34;
    > printf("%u\n", x );


    printf("%" PRIu32 "\n", x);

    > that'll work, it seems, as long as i'm on a 32-bit platform. If i
    > reconfigure the software to use:
    >
    > typedef uint64_t id_type;
    >
    > then i've got a problem: i've got to change the printf() to use to %llu
    > or %lu (depends on the bitness of the platform, apparently) to avoid a
    > warning from the compiler (a reasonable warning, IMO, and not one i
    > want to ignore).


    printf("%" PRIu64 "\n", x);

    > Is there a canon solution to dealing with this?


    #define PRIuID PRIu64

    Define this near id_type, so that it is obvious you need to update this
    when you update id_type's definition. Use this macro when printing.

    > A related point: what are the proper printf specifiers to use for each
    > uint type (8-64 bits)? As best as i can determine they are:
    >
    > uint8_t: %hhu
    > uint16_t: %hu
    > uint32_t: %u
    > uint64_t: %llu or %lu?
    >
    > :-?
    >
    > i seem to remember reading that %hhX and %llX are GNU-specific (or not
    > standard), but i can't find anything to back that up with at the
    > moment.


    %hhu is for unsigned char.
    %hu is for unsigned short.
    %u is for unsigned int.
    %lu is for unsigned long int.
    %llu is for unsigned long long int.

    All of the above are standard C format specifiers, although some have
    only become standard as of 1999 (and are less widely supported), but none
    of them should be used for uintN_t types. PRIuN (where N is 8, 16, etc.)
    are for uintN_t types.
     
    Harald van Dijk, Jan 11, 2009
    #3
  4. Stephan Beal

    Stephan Beal Guest

    Re: Looking for tips for portable printf() specifiers for signed intsof varying sizes

    On Jan 11, 11:05 pm, Falcon Kirtaran
    <> wrote:
    > %llu (and %Lu, which is equivalent when using gnu) aren't standard
    > because long long unsigned int is not a standard type, if memory serves.


    i thought long long is C99 standard (but of course not supported
    everywhere). Doesn't that imply the standardization of unsigned long
    long as well?

    > Just to clarify, what do you mean by core int types?


    8-64-bit ints

    >  Also, do you know
    > how they are configured?  If it is a macro, I don't know if you can do
    > too much.  If it is configured at runtime, you would need to use runtime
    > type identification to generate your format strings.


    It's a bit of an odd beast, really. A macro defines the bitedness
    (8/16/32/64). Then we #if/#else a typedef based on that bitedness. The
    code is:

    /* ... 50(!) lines of docs snipped ... */
    #define WHEFS_ID_TYPE_BITS 16

    #if WHEFS_ID_TYPE_BITS == 8
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 8-bit IDs"
    typedef uint8_t whefs_id_type;
    #elif WHEFS_ID_TYPE_BITS == 16
    /* the most realistic value, IMO. */
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 16-bit IDs"
    typedef uint16_t whefs_id_type;
    #elif WHEFS_ID_TYPE_BITS == 32
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 32-bit IDs"
    typedef uint32_t whefs_id_type;
    #elif WHEFS_ID_TYPE_BITS == 64
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 64-bit IDs"
    typedef uint64_t whefs_id_type;
    #else
    # error "WHEFS_ID_TYPE_BITS must be one of: 16, 32, 64"
    #endif


    i need a macro (i'd prefer an enum value) for WHEFS_ID_TYPE_BITS
    because small parts of the code need to be conditionally compiled
    based on the width of the type. i also must use types of known widths.
    e.g. i can't rely on size_t because it's not the same size on all
    platforms (i found out the hard way). Thus i'm using the <stdint.h>
    uint8_t .. uint64_t. Signed numbers are invalid and of no concern for
    my use case.
     
    Stephan Beal, Jan 11, 2009
    #4
  5. Stephan Beal

    Ian Collins Guest

    Re: Looking for tips for portable printf() specifiers for signedints of varying sizes

    Stephan Beal wrote:
    > On Jan 11, 11:05 pm, Falcon Kirtaran
    > <> wrote:
    >> %llu (and %Lu, which is equivalent when using gnu) aren't standard
    >> because long long unsigned int is not a standard type, if memory serves.

    >
    > i thought long long is C99 standard (but of course not supported
    > everywhere). Doesn't that imply the standardization of unsigned long
    > long as well?
    >

    It does, both long long and unsigned long long are standard.

    > It's a bit of an odd beast, really. A macro defines the bitedness
    > (8/16/32/64). Then we #if/#else a typedef based on that bitedness. The
    > code is:
    >
    > /* ... 50(!) lines of docs snipped ... */
    > #define WHEFS_ID_TYPE_BITS 16
    >
    > #if WHEFS_ID_TYPE_BITS == 8
    > # define WHEFS_MAGIC_STRING "whefs version 20090109 with 8-bit IDs"


    Here would be the pace to define the appropriate (see Harald's post)
    conversion specifier.

    > typedef uint8_t whefs_id_type;


    --
    Ian Collins
     
    Ian Collins, Jan 11, 2009
    #5
  6. Re: Looking for tips for portable printf() specifiers for signedints of varying sizes

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Ian Collins wrote:
    > Stephan Beal wrote:
    >> On Jan 11, 11:05 pm, Falcon Kirtaran
    >> <> wrote:
    >>> %llu (and %Lu, which is equivalent when using gnu) aren't standard
    >>> because long long unsigned int is not a standard type, if memory serves.

    >> i thought long long is C99 standard (but of course not supported
    >> everywhere). Doesn't that imply the standardization of unsigned long
    >> long as well?
    >>

    > It does, both long long and unsigned long long are standard.


    Hmm. I most probably stand corrected.

    >
    >> It's a bit of an odd beast, really. A macro defines the bitedness
    >> (8/16/32/64). Then we #if/#else a typedef based on that bitedness. The
    >> code is:
    >>
    >> /* ... 50(!) lines of docs snipped ... */
    >> #define WHEFS_ID_TYPE_BITS 16
    >>
    >> #if WHEFS_ID_TYPE_BITS == 8
    >> # define WHEFS_MAGIC_STRING "whefs version 20090109 with 8-bit IDs"

    >
    > Here would be the pace to define the appropriate (see Harald's post)
    > conversion specifier.
    >
    >> typedef uint8_t whefs_id_type;

    >


    - --
    - --Falcon Darkstar Kirtaran
    - --
    - --OpenPGP: (7902:4457) 9282:A431

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.9 (GNU/Linux)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iQIcBAEBAgAGBQJJangoAAoJEKmxP9YxEE4rveEP+wQ9Ke28sUSRvP8ZYXCQkXtQ
    cGxQONq9VGRbkO2zIp3GRwDZdPjHDBdpCPLie73dKnNRUTBJGchhRMvqHF7BLguW
    HjxvZ62MXr6H6gx8iRttGFX7wDl0bm3IjBU6eWfUpZ3Dx8jAyjhkhMq9dlVLSFjT
    4w/sNMdYkONk0KilHdZaeE1+J1QrwiwODkuq+KOCPJ1klgLX557yeMXiiWcbcCHA
    uH5P/rkKXG3dAe9bWTgregphTH3uj7lmswIFllFuBcYntzVXGxUAxkfs7ueRcqPv
    J9DHulcCt0MwdmZinE0h5ctAKg0Of/cknLKfzM46ecQK2KQ+DqQAXNiVFeAT2kqy
    V18K0MfqKIOzijVA0M/nk+qRi+6HfVHZMI7yCtiNg/KG9FIx6T9F8f4e0k1DLUYC
    CeostybG+xu22lwb9Kingh0wy0gSk9g6MpH2LCvr+BdDbsAPCmhBdEMk+4CXjD2P
    tKo8R+JgB4zlVAha+04cD5AIeJb0hDtnkgUdGtPKh8DKIr7HfcvSeQB5tNPm4SMt
    vyWpvlVi7ZzXbFeu06s0d0TE9FoEdPKfruDUHkNVMA3B+ILUdm+VrwYwQycwPi+o
    PY/F53DjzKuzzvtYk85xWNGUV6zyesgo4fKzko4nIUgpY37fTvQ/odjC7GCQOJjv
    tfpBf8kORkSW9NywrUK0
    =zUiP
    -----END PGP SIGNATURE-----
     
    Falcon Kirtaran, Jan 11, 2009
    #6
  7. Re: Looking for tips for portable printf() specifiers for signed ints of varying sizes

    On Sun, 11 Jan 2009 15:05:02 -0700, Falcon Kirtaran
    <> wrote:

    >-----BEGIN PGP SIGNED MESSAGE-----
    >Hash: SHA1
    >
    >Stephan Beal wrote:
    >> Hi, all!
    >>
    >> i am working on a piece of software where the size of one of the core
    >> int types is configurable to be 8, 16, 32, or 64 bits (uint8_t ..
    >> uint64_t). That's all working fine and well, but i've got a slight
    >> problem when it comes to outputing them: my printf() specifiers have
    >> to be different depending on the exact width of the type. (Granted,
    >> all of that is debugging code, and doesn't directly affect the
    >> library, but it annoys the hell out of me nonetheless.)
    >>
    >> e.g.:
    >>
    >> typedef uint32_t id_type;
    >> ...
    >> id_type x = 34;
    >> printf("%u\n", x );
    >>
    >> that'll work, it seems, as long as i'm on a 32-bit platform. If i
    >> reconfigure the software to use:
    >>
    >> typedef uint64_t id_type;
    >>
    >> then i've got a problem: i've got to change the printf() to use to
    >> %llu or %lu (depends on the bitness of the platform, apparently) to
    >> avoid a warning from the compiler (a reasonable warning, IMO, and not
    >> one i want to ignore).
    >>
    >> Is there a canon solution to dealing with this?
    >>
    >> A related point: what are the proper printf specifiers to use for each
    >> uint type (8-64 bits)? As best as i can determine they are:
    >>
    >> uint8_t: %hhu
    >> uint16_t: %hu
    >> uint32_t: %u
    >> uint64_t: %llu or %lu?
    >>
    >> :-?
    >>
    >> i seem to remember reading that %hhX and %llX are GNU-specific (or not
    >> standard), but i can't find anything to back that up with at the
    >> moment.
    >>
    >> Are there *standard* specifiers i can reliably use for each of those
    >> types?

    >
    >%llu (and %Lu, which is equivalent when using gnu) aren't standard
    >because long long unsigned int is not a standard type, if memory serves.


    It is in C99 (section 6.2.5-4).

    --
    Remove del for email
     
    Barry Schwarz, Jan 11, 2009
    #7
  8. Re: Looking for tips for portable printf() specifiers for signed ints of varying sizes

    On Sun, 11 Jan 2009 13:59:44 -0800 (PST), Stephan Beal
    <> wrote:

    >Hi, all!
    >
    >i am working on a piece of software where the size of one of the core
    >int types is configurable to be 8, 16, 32, or 64 bits (uint8_t ..
    >uint64_t). That's all working fine and well, but i've got a slight
    >problem when it comes to outputing them: my printf() specifiers have
    >to be different depending on the exact width of the type. (Granted,
    >all of that is debugging code, and doesn't directly affect the
    >library, but it annoys the hell out of me nonetheless.)


    One simple solution would be to cast the arguments in you calls to
    printf to the maximum size you compiler will support (presumably
    uint64_t) and always use the format PRIu64 defined in inttypes.h. As
    you say, it is only in the debugging code. If your system doesn't
    provide PRIu64, you could probably achieve the same affect with either
    unsigned long long or unsigned long and llu or lu.

    >
    >e.g.:
    >
    >typedef uint32_t id_type;


    Is this not a standard type provided by your system in stdint.h

    >...
    >id_type x = 34;
    >printf("%u\n", x );
    >
    >that'll work, it seems, as long as i'm on a 32-bit platform. If i
    >reconfigure the software to use:
    >
    >typedef uint64_t id_type;
    >
    >then i've got a problem: i've got to change the printf() to use to
    >%llu or %lu (depends on the bitness of the platform, apparently) to
    >avoid a warning from the compiler (a reasonable warning, IMO, and not
    >one i want to ignore).
    >
    >Is there a canon solution to dealing with this?
    >
    >A related point: what are the proper printf specifiers to use for each
    >uint type (8-64 bits)? As best as i can determine they are:
    >
    >uint8_t: %hhu
    >uint16_t: %hu
    >uint32_t: %u
    >uint64_t: %llu or %lu?


    Check section 7.8 and header inttypes.h.

    >
    >:-?
    >
    >i seem to remember reading that %hhX and %llX are GNU-specific (or not
    >standard), but i can't find anything to back that up with at the
    >moment.
    >
    >Are there *standard* specifiers i can reliably use for each of those
    >types?


    --
    Remove del for email
     
    Barry Schwarz, Jan 11, 2009
    #8
  9. Stephan Beal

    Ben Pfaff Guest

    Re: Looking for tips for portable printf() specifiers for signed ints of varying sizes

    Stephan Beal <> writes:

    > typedef uint32_t id_type;
    > ...
    > id_type x = 34;
    > printf("%u\n", x );
    >
    > that'll work, it seems, as long as i'm on a 32-bit platform. If i
    > reconfigure the software to use:
    >
    > typedef uint64_t id_type;


    Use a macro:
    #include <inttypes.h>
    typedef uint32_t id_type;
    #define PRINT_ID PRIu32

    Then you can print it with:
    id_type x = 34;
    printf("%"PRINT_ID"\n", x);

    And when you change to 64-bit, then:
    #include <inttypes.h>
    typedef uint64_t id_type;
    #define PRINT_ID PRIu64
    and the code to print is updated automatically.
    --
    Peter Seebach on C99:
    "[F]or the most part, features were added, not removed. This sounds
    great until you try to carry a full-sized printout of the standard
    around for a day."
     
    Ben Pfaff, Jan 12, 2009
    #9
  10. Re: Looking for tips for portable printf() specifiers for signed ints of varying sizes

    Barry Schwarz <> writes:
    > On Sun, 11 Jan 2009 13:59:44 -0800 (PST), Stephan Beal
    > <> wrote:
    >>i am working on a piece of software where the size of one of the core
    >>int types is configurable to be 8, 16, 32, or 64 bits (uint8_t ..
    >>uint64_t). That's all working fine and well, but i've got a slight
    >>problem when it comes to outputing them: my printf() specifiers have
    >>to be different depending on the exact width of the type. (Granted,
    >>all of that is debugging code, and doesn't directly affect the
    >>library, but it annoys the hell out of me nonetheless.)

    >
    > One simple solution would be to cast the arguments in you calls to
    > printf to the maximum size you compiler will support (presumably
    > uint64_t) and always use the format PRIu64 defined in inttypes.h. As
    > you say, it is only in the debugging code. If your system doesn't
    > provide PRIu64, you could probably achieve the same affect with either
    > unsigned long long or unsigned long and llu or lu.

    [...]

    uintmax_t is going to be the largest unsigned type in any conforming
    C99 implementation; <inttypes.h> provides conversion specifiers for
    it. It's very likely to be the same as uint64_t, but an
    implementation could provide a larger type -- or might provide, say,
    uint80_t but not uint64_t. uintmax_t is guaranteed to exist.

    In a conforming C90 implementation, unsigned long is the largest
    unsigned type.

    The tricky part is supporting pre-C99 implementations that support
    long long, and perhaps even implementations that support long long but
    not "%llu" (particularly if the compiler and runtime library are from
    different suppliers).

    --
    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 12, 2009
    #10
  11. Stephan Beal

    Stephan Beal Guest

    Re: Looking for tips for portable printf() specifiers for signed intsof varying sizes

    Thanks again to all of your for your insights and clarifications -
    this has been really helpful. :)

    i've settled on essentially what several of you suggested:

    #if WHEFS_ID_TYPE_BITS == 8
    /* for very, very limited filesystems. There's lots of room for
    overflows here! */
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 8-bit IDs"
    # define WHEFS_ID_PRINTF_SPEC PRIu8
    typedef uint8_t whefs_id_type;
    #elif WHEFS_ID_TYPE_BITS == 16
    /* the most realistic value, IMO. */
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 16-bit IDs"
    # define WHEFS_ID_PRINTF_SPEC PRIu16
    typedef uint16_t whefs_id_type;
    #elif WHEFS_ID_TYPE_BITS == 32
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 32-bit IDs"
    # define WHEFS_ID_PRINTF_SPEC PRIu32
    typedef uint32_t whefs_id_type;
    #elif WHEFS_ID_TYPE_BITS == 64
    # define WHEFS_ID_PRINTF_SPEC PRIu16
    # define WHEFS_MAGIC_STRING "whefs version 20090109 with 64-bit IDs"
    typedef uint64_t whefs_id_type;
    #else
    # error "WHEFS_ID_TYPE_BITS must be one of: 8, 16, 32, 64"
    #endif
     
    Stephan Beal, Jan 12, 2009
    #11
  12. Re: Looking for tips for portable printf() specifiers for signed ints of varying sizes

    Stephan Beal <> writes:
    > Thanks again to all of your for your insights and clarifications -
    > this has been really helpful. :)
    >
    > i've settled on essentially what several of you suggested:
    >
    > #if WHEFS_ID_TYPE_BITS == 8
    > /* for very, very limited filesystems. There's lots of room for
    > overflows here! */
    > # define WHEFS_MAGIC_STRING "whefs version 20090109 with 8-bit IDs"
    > # define WHEFS_ID_PRINTF_SPEC PRIu8
    > typedef uint8_t whefs_id_type;
    > #elif WHEFS_ID_TYPE_BITS == 16
    > /* the most realistic value, IMO. */
    > # define WHEFS_MAGIC_STRING "whefs version 20090109 with 16-bit IDs"
    > # define WHEFS_ID_PRINTF_SPEC PRIu16
    > typedef uint16_t whefs_id_type;
    > #elif WHEFS_ID_TYPE_BITS == 32
    > # define WHEFS_MAGIC_STRING "whefs version 20090109 with 32-bit IDs"
    > # define WHEFS_ID_PRINTF_SPEC PRIu32
    > typedef uint32_t whefs_id_type;
    > #elif WHEFS_ID_TYPE_BITS == 64
    > # define WHEFS_ID_PRINTF_SPEC PRIu16
    > # define WHEFS_MAGIC_STRING "whefs version 20090109 with 64-bit IDs"
    > typedef uint64_t whefs_id_type;
    > #else
    > # error "WHEFS_ID_TYPE_BITS must be one of: 8, 16, 32, 64"
    > #endif


    Note that this depends on the presence and correctness of the
    <inttypes.h> header. Since this is new in C99, some implementations
    might not yet support it. In particular, I've heard that Microsoft
    has shown very little interest in supporting C99, but I don't know
    the details.

    Another alternative is to use a format for a very large type and
    convert all your whefs_id_type arguments to that type when passing
    them to printf:

    whefs_id_type foo = <whatever>;
    printf("foo = %lu\n", (unsigned long)foo);

    --
    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 12, 2009
    #12
  13. Stephan Beal

    Richard Bos Guest

    Re: Looking for tips for portable printf() specifiers for signed ints of varying sizes

    Keith Thompson <> wrote:

    > Stephan Beal <> writes:


    > > #if WHEFS_ID_TYPE_BITS == 8
    > > /* for very, very limited filesystems. There's lots of room for
    > > overflows here! */
    > > # define WHEFS_MAGIC_STRING "whefs version 20090109 with 8-bit IDs"
    > > # define WHEFS_ID_PRINTF_SPEC PRIu8
    > > typedef uint8_t whefs_id_type;


    ....and so on...

    > Note that this depends on the presence and correctness of the
    > <inttypes.h> header. Since this is new in C99, some implementations
    > might not yet support it.


    OTOH, I would expect any reasonable implementation to have both uint8_t
    and PRIu8, or neither, but not one without the other...

    > In particular, I've heard that Microsoft has shown very little interest
    > in supporting C99, but I don't know the details.


    ....OTGH, some software companies simply aren't reasonable.

    Richard
     
    Richard Bos, Jan 15, 2009
    #13
  14. Re: Looking for tips for portable printf() specifiers for signedints of varying sizes

    -----BEGIN PGP SIGNED MESSAGE-----
    Hash: SHA1

    Richard Bos wrote:
    > Keith Thompson <> wrote:
    >
    >> Stephan Beal <> writes:

    >
    >>> #if WHEFS_ID_TYPE_BITS == 8
    >>> /* for very, very limited filesystems. There's lots of room for
    >>> overflows here! */
    >>> # define WHEFS_MAGIC_STRING "whefs version 20090109 with 8-bit IDs"
    >>> # define WHEFS_ID_PRINTF_SPEC PRIu8
    >>> typedef uint8_t whefs_id_type;

    >
    > ...and so on...
    >
    >> Note that this depends on the presence and correctness of the
    >> <inttypes.h> header. Since this is new in C99, some implementations
    >> might not yet support it.

    >
    > OTOH, I would expect any reasonable implementation to have both uint8_t
    > and PRIu8, or neither, but not one without the other...
    >
    >> In particular, I've heard that Microsoft has shown very little interest
    >> in supporting C99, but I don't know the details.

    >
    > ...OTGH, some software companies simply aren't reasonable.
    >
    > Richard


    If memory serves most of the new things present in C99 are implemented
    in microsoft's tripe as proprietary extensions.

    - --
    - --Falcon Darkstar Kirtaran
    - --
    - --OpenPGP: (7902:4457) 9282:A431

    -----BEGIN PGP SIGNATURE-----
    Version: GnuPG v2.0.9 (GNU/Linux)
    Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

    iQIcBAEBAgAGBQJJb4ueAAoJEKmxP9YxEE4rzP4QAKUH32e5fY7W7fhmwjN6Ra4T
    J47jwAwdbsDWQyG2HOWu5uK4UNck//NRWDFrFLmr73SNUpZzKdqWf8DiTWzfepi+
    HHWW4y4PN3JfchJykxuV8I/w+PWbuFCEpvdsiVGp8Md4vIi6P26mRYRyM8N4CMQL
    L+W3Vu57SV5Q0s1IF5YsvkTgeELTMbdn5kAVip+PiRwYJfxG6PRXmuKcCy5N/3A9
    QovsFA095JJT6GklsABCrQmZerHltyPA873kwaPpsZ2FbTZZRbkN8W89UWamA9n5
    XKOY0J42+d/01H7/tAspn56XDABH6JRJi2WjshL1PrJtIN2M4uePEhVQrUe1P6kt
    aarKNZVpnxXwofnpd1KTwDNF+a3THj3BKTtbhmZ3SAC5J6d99FZwUuOF/nfc3jzR
    QgXcgAbFDuUF40cpfGjqDibEfGpVOhWAYktCvAvJmxbH/cu2lKAa1giqQijsI693
    C5Ts70xuYx7GW/UHlzBSTlpP4hC9k9Yodx3CS3RgQqkdIRysuZuYbItOQlib7dly
    M2/RwXdQ5aWoV1WkWBCMylRyQlj7dFtfwjJmpxrVSiRphdBNuJy5Y16riyRp0m0I
    8gphNsC5gygIe/8YKLfWp+DWdKi6nX45xsO4bHj+u3BOt/gRYoPc1oPOYiosPjyD
    yGrj18Tot8/aAaPKaV26
    =VRmI
    -----END PGP SIGNATURE-----
     
    Falcon Kirtaran, Jan 15, 2009
    #14
    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. Eli Bendersky
    Replies:
    1
    Views:
    1,170
    Mike Treseler
    Mar 1, 2006
  2. Replies:
    3
    Views:
    566
    Mark P
    Apr 3, 2005
  3. Skybuck Flying

    ints ints ints and ints

    Skybuck Flying, Jul 8, 2004, in forum: C Programming
    Replies:
    24
    Views:
    836
    Jack Klein
    Jul 10, 2004
  4. rh00667
    Replies:
    2
    Views:
    574
    rh00667
    Mar 2, 2007
  5. David Mathog
    Replies:
    8
    Views:
    3,894
    Keith Thompson
    Jan 26, 2011
Loading...

Share This Page