%llu on 64bit architecture

Discussion in 'C Programming' started by Max Laier, Jun 26, 2003.

  1. Max Laier

    Max Laier Guest

    What should a compiler on a 64bit platform do with the following:

    unit64_t x=1234567;
    printf("%llu", x);

    On 32Bit unit64_t is usually a macro for "unsigned long long" so above
    example is perfectly right.
    On 64Bit unit64_t is usually a macro for "unsigned long" so above code might
    cause a warning.

    Of course you can use PRIu64 to avoid that, but many docs on printf tell

    "The optional character sequence ll, specifying that a following d, i, o, u,
    x, or X conversion corresponds to a **quad** int or unsigned **quad** int
    argument, or that a following n conversion corresponds to a pointer to a
    quad int argument. The use of q has been deprecated as conversion

    A quad, however, is 64bit on every platform and hence %llu should print
    uint64_t without a warning.

    What do you think? Is this right or wrong?
    What is the real meaning of %llu:
    - print a "long long" variable?
    - or print a 64bit varibale?

    Max Laier, Jun 26, 2003
    1. Advertisements

  2. Max Laier

    dbtid Guest

    Max Laier wrote:

    Those are probably not macros. They are probably typedefs.

    dbtid, Jun 26, 2003
    1. Advertisements

  3. According to C99, the ll length modifier is used with unsigned long
    long int or long long int depending on the conversion specifier. If
    the argument is not of the correct type for the conversion
    specification, then the behavior is undefined. From the documentation
    that you provided, it seems that they have provided an extension for

    Best wishes,

    Robert W Hand, Jun 26, 2003
  4. Max Laier

    Chris Torek Guest

    It should produce a diagnostic, because "unit64_t" is not syntactically
    valid. :)

    Obviously you meant "uint64_t", and meant to imply that some header
    file was included first so that uint64_t is a typedef for some other
    type. Then the question is: what other type? If uint64_t is an
    alias for "unsigned long long", the above is valid. If it is an
    alias for some other type, the call probably violates various
    "shall"s that are outside "Constraints" section, and hence is not
    only wrong but also does not require a diagnostic.
    The problem here is that C does not have a type called "quad".

    C89 does not even have the "long long" type, and does not guarantee
    the existence of any 64-bit type.

    Some systems, including the BSD Unix-like systems, needed a 64-bit
    type long before the C99 standard existed. So, in 1991, we[%]
    charged on ahead and used GCC's 64-bit "long long" extension, gave
    it a shorter name we invented and called "quad", and added the
    "%qd" format to printf. We put this in the manual pages and noted
    that it was non-ANSI. If you are using a BSD-based system, this
    is likely where the above came from. If you are using a system
    that cloned ideas from our BSD-based systems, it is probably still
    where the above came from.

    [%Footnote: primarily Keith Bostic and myself.]

    Today, you are using our 1991-era name and expecting it to mean
    something specific in C99. Alas, we are not entirely lucky --
    while C99 added "long long", they did not call it "quad" nor use
    "%qd" as a printf() format.
    According to C99, this is what it means.

    If you are using an earlier version of C, it has *no* defined
    meaning (which is how we were able to run off with it and do
    something we considered useful -- but if you use our meaning, you
    run the risk of having any OTHER implementation run off with it
    and do something different).
    On the systems on which we did our thing, these were the same. On
    C99 systems, these are not necessarily the same. *You* must choose:
    whether to use C99, or C89-with-our-extensions, or C89-with-someone-
    else's-extensions, or whatever it is you like.
    Chris Torek, Jun 26, 2003
  5. Max Laier

    Dan Pop Guest

    In the general case, it is undefined behaviour, because uint64_t need not
    be a typedef for usigned long long.

    The correct versions are:

    uint64_t x = 1234567;
    printf("%" PRIu64, x);


    unsigned long long x = 1234567;
    printf("%llu", x);

    Note that this issue has absolutely nothing to do with the platform's
    size. uint64_t and PRIu64 need not be defined by the implementation
    (unless it provides a "native" type with the required properties).

    Dan Pop, Jun 27, 2003
    1. Advertisements

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.