is this compiler diagnostic legal?

Discussion in 'C Programming' started by Rainer Zufall, Feb 11, 2008.

  1. consider this code

    #include <stdio.h>
    int main(void)
    {
    unsigned long ul = 42;
    printf("0x%08lX\n", ul);
    return 0;
    }

    One compiler I tried issues the following diagnostic:

    Warning foo.c: 5 printf argument mismatch for format X. Expected long int got unsigned long
    0 errors, 1 warning

    I always thought %X requires an unsigned quantity.

    Who is right here, my understanding of the standard, or the compiler?

    --
    Rainer Zufall;
    Rainer Zufall, Feb 11, 2008
    #1
    1. Advertising

  2. Rainer Zufall

    Martin Guest

    On Feb 11, 1:38 pm, Rainer Zufall <>
    wrote:
    > I always thought %X requires an unsigned quantity.


    %lX converts a long argument into an unsigned long then to an unsigned
    sequence of (in the case of %08lX) at least 8 hexadecimal digits,
    padded with leading zeros if necessary.

    The compiler is correct.

    --
    Martin
    Martin, Feb 11, 2008
    #2
    1. Advertising

  3. In article <>,
    Martin <> wrote:
    >On Feb 11, 1:38=A0pm, Rainer Zufall <>
    >wrote:


    >> I always thought %X requires an unsigned quantity.


    >%lX converts a long argument into an unsigned long then to an unsigned
    >sequence of (in the case of %08lX) at least 8 hexadecimal digits,
    >padded with leading zeros if necessary.


    C89 4.9.6.1 The fprintf Function

    o,u,x,X The unsigned int argument is converted to unsigned octal (o),
    unsigned decimal (u), or unsigned hexadecimal notation
    (x or X) [...]
    --
    "No one has the right to destroy another person's belief by
    demanding empirical evidence." -- Ann Landers
    Walter Roberson, Feb 11, 2008
    #3
  4. On Feb 11, 8:38 am, Rainer Zufall <>
    wrote:
    > consider this code
    >
    > #include <stdio.h>
    > int main(void)
    > {
    > unsigned long ul = 42;
    > printf("0x%08lX\n", ul);
    > return 0;
    > }
    >
    > One compiler I tried issues the following diagnostic:
    >
    > Warning foo.c: 5 printf argument mismatch for format X. Expected long int got unsigned long
    > 0 errors, 1 warning
    >
    > I always thought %X requires an unsigned quantity.
    >
    > Who is right here, my understanding of the standard, or the compiler?


    %X does always require an unsigned type, %lX requires a type of
    unsigned long which you properly provided. You are correct, your
    compiler is wrong.

    --
    Robert Gamble
    Robert Gamble, Feb 11, 2008
    #4
  5. Rainer Zufall

    Martin Guest

    On Feb 11, 1:38 pm, Rainer Zufall <>
    wrote:
    > I always thought %X requires an unsigned quantity.
    >
    > Who is right here, my understanding of the standard, or the compiler?



    I've looked into this after seeing the previous replies.

    Plauger in "The Standard C Library" states that the four conversion
    specifiers lo, lX, lx, and lu expect long arguments, which are then
    converted to unsigned long.

    K&R2 states that o, x, X, u expect the argument type to be int (i.e.,
    signed) - although the errata for that book corrects that to unsigned
    int. That implies lx expects the argument type to be unsigned long.

    However, the most important resource, the C Standard, specifies
    clearly that unsigned long is indeed the expected argument type for
    the conversion specifiers, including the one you queried.

    The compiler has got it wrong.

    I shall annotate Plauger accordingly.

    --
    Martin
    Martin, Feb 11, 2008
    #5
  6. Martin <> writes:
    > On Feb 11, 1:38 pm, Rainer Zufall <>
    > wrote:
    >> I always thought %X requires an unsigned quantity.

    >
    > %lX converts a long argument into an unsigned long then to an unsigned
    > sequence of (in the case of %08lX) at least 8 hexadecimal digits,
    > padded with leading zeros if necessary.
    >
    > The compiler is correct.


    For context, the code was:

    #include <stdio.h>
    int main(void)
    {
    unsigned long ul = 42;
    printf("0x%08lX\n", ul);
    return 0;
    }

    and the warning was:

    Warning foo.c: 5 printf argument mismatch for format X. Expected long int got unsigned long
    0 errors, 1 warning

    The format requires an unsigned long argument. The compiler's warning
    is incorrect. This isn't actually a violation of the standard; the
    standard allows additional diagnostics, and doesn't require them to be
    factually correct. But it's certainly a bug.

    If the actual argument were of type signed long, a compiler could
    reasonably refrain from warning about it, but it cannot reasonably
    warn about this call, which is perfectly correct.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Feb 11, 2008
    #6
  7. Am Mon, 11 Feb 2008 14:38:16 +0100 (CET), Rainer Zufall <> schrieb:

    >
    >consider this code
    >
    > #include <stdio.h>
    > int main(void)
    > {
    > unsigned long ul = 42;
    > printf("0x%08lX\n", ul);
    > return 0;
    > }
    >
    >One compiler I tried issues the following diagnostic:
    >
    > Warning foo.c: 5 printf argument mismatch for format X. Expected long int got unsigned long
    > 0 errors, 1 warning
    >
    >I always thought %X requires an unsigned quantity.
    >
    >Who is right here, my understanding of the standard, or the compiler?


    LCC-WIN32 shows this warning also, but I think it has more sense.

    unsigned long is always positive.

    signed long can positive or negative be.

    What if I want to print negative numbers in HeX?
    Hans Schneider, Feb 11, 2008
    #7
  8. Hans Schneider <> writes:
    > Am Mon, 11 Feb 2008 14:38:16 +0100 (CET), Rainer Zufall
    > <> schrieb:
    >>
    >>consider this code
    >>
    >> #include <stdio.h>
    >> int main(void)
    >> {
    >> unsigned long ul = 42;
    >> printf("0x%08lX\n", ul);
    >> return 0;
    >> }
    >>
    >>One compiler I tried issues the following diagnostic:
    >>
    >> Warning foo.c: 5 printf argument mismatch for format X. Expected long int got unsigned long
    >> 0 errors, 1 warning
    >>
    >>I always thought %X requires an unsigned quantity.
    >>
    >>Who is right here, my understanding of the standard, or the compiler?

    >
    > LCC-WIN32 shows this warning also, but I think it has more sense.


    Since there's nothing wrong with the code, I hope lcc-win32 doesn't
    show a warning for it.

    > unsigned long is always positive.
    >
    > signed long can positive or negative be.
    >
    > What if I want to print negative numbers in HeX?


    There's no direct way to do that using printf.

    If x is your number, you could do something like this:

    printf("x = %s0x%x\n",
    x < 0 ? "-" : "",
    (unsigned)abs(x));

    but it's not guaranteed to work for x == INT_MIN.

    --
    Keith Thompson (The_Other_Keith) <>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Feb 12, 2008
    #8
  9. Rainer Zufall

    jacob navia Guest

    Hans Schneider wrote:
    > LCC-WIN32 shows this warning also, but I think it has more sense.
    >


    Not in the latest version. We had a discussion about this some months
    ago and I fixed it, as far as I can remember. In any case I see
    absolutely no warning with the latest version of lcc-win

    --
    jacob navia
    jacob at jacob point remcomp point fr
    logiciels/informatique
    http://www.cs.virginia.edu/~lcc-win32
    jacob navia, Feb 12, 2008
    #9
  10. Robert Gamble <> wrote:
    > %X does always require an unsigned type, %lX requires a
    > type of unsigned long...


    %X requires unsigned int, but observe that %hX requires
    the promoted type of unsigned short, which may be int.

    --
    Peter
    Peter Nilsson, Feb 12, 2008
    #10
  11. Rainer Zufall

    Thad Smith Guest

    Robert Gamble wrote:

    > %X does always require an unsigned type, %lX requires a type of
    > unsigned long which you properly provided.


    That is what I expect, but the Standard is amazingly ambiguous:

    7.9.6.1, p7:
    The length modifiers and their meanings are:
    ....
    l (ell) Specifies that a following d, i, o, u, x, or X conversion specifier
    applies to a long int or unsigned long int argument; ...

    Whose choice is it whether it should be long int or unsigned long int?

    Then p8:
    The conversion specifiers and their meanings are:
    ....
    o,u,x,X The unsigned int argument is converted to unsigned octal (o),
    unsigned decimal (u), or unsigned hexadecimal notation (x or X) in the
    style dddd; ...

    Here the X specifier says that it requires an unsigned int argument with no
    mention of an alternative, no mention of arument type for %lX, so someone
    has to choose whether the argument is an long int or unsigned long int and
    on what basis?

    This is a where I think I know the intent, but have a hard time proving it
    with the wording in the Standard.

    --
    Thad
    Thad Smith, Feb 12, 2008
    #11
    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. Michael Johnson Sr.

    System.Diagnostic.Process and disfunctional process

    Michael Johnson Sr., Feb 17, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    1,951
    Michael Johnson Sr.
    Feb 17, 2004
  2. Michael Johnson Sr.

    System.Diagnostic.Process and disfunctional process.

    Michael Johnson Sr., Feb 17, 2004, in forum: ASP .Net
    Replies:
    0
    Views:
    318
    Michael Johnson Sr.
    Feb 17, 2004
  3. Andrew

    Managing Diagnostic Listener Files

    Andrew, Aug 5, 2004, in forum: ASP .Net
    Replies:
    4
    Views:
    485
    Andrew
    Aug 6, 2004
  4. INT_MIN and compiler diagnostic

    , Feb 28, 2007, in forum: C Programming
    Replies:
    41
    Views:
    1,178
    Chris Torek
    Mar 26, 2007
  5. Richard Lionheart

    Got one compiler diagnostic I can't handle

    Richard Lionheart, Mar 22, 2006, in forum: C++
    Replies:
    2
    Views:
    408
    Richard Lionheart
    Mar 22, 2006
Loading...

Share This Page