ULONG_MAX

Discussion in 'C Programming' started by ccwork, Apr 20, 2005.

  1. ccwork

    ccwork Guest

    Hi all,
    Is the following codes Standard C?

    unsigned long number = ULONG_MAX;
    unsigned long result = 0;

    result = (unsigned long) number % ULONG_MAX;
    printf("ULONG_MAX=%lu, number=%lu, result=%lu\n", ULONG_MAX, number,
    result);

    My compiler (VC++ if you want to know), in debug mode, give:
    ULONG_MAX=4294967295, number3=4294967295, result3=0

    However, in release mode, it gives:
    ULONG_MAX=4294967295, number3=4294967295, result3=4294967295

    I don't know if the code trigger undefined behaviour or it is the
    compiler bug.
     
    ccwork, Apr 20, 2005
    #1
    1. Advertising

  2. "ccwork" <> writes:
    > Is the following codes Standard C?
    >
    > unsigned long number = ULONG_MAX;
    > unsigned long result = 0;
    >
    > result = (unsigned long) number % ULONG_MAX;
    > printf("ULONG_MAX=%lu, number=%lu, result=%lu\n", ULONG_MAX, number,
    > result);
    >
    > My compiler (VC++ if you want to know), in debug mode, give:
    > ULONG_MAX=4294967295, number3=4294967295, result3=0
    >
    > However, in release mode, it gives:
    > ULONG_MAX=4294967295, number3=4294967295, result3=4294967295
    >
    > I don't know if the code trigger undefined behaviour or it is the
    > compiler bug.


    It looks like it could be a compiler bug, but it's hard to be sure
    since what you posted either isn't exactly your actual code, or isn't
    your actual output. The printf statement has "number=" and "result=",
    but the output you showed us has "number3=" and "result3=". It's
    impossible to tell what other subtle differences there might be that
    could explain the discrepancy.

    Also, the cast is superfluous; number is already of type unsigned
    long, so casting it is unnecessary (unless it's necessary to trigger
    the compiler bug).

    Here's a complete self-contained program (I've left the cast in place):

    #include <stdio.h>
    #include <limits.h>
    int main(void)
    {
    unsigned long number = ULONG_MAX;
    unsigned long result = 0;

    result = (unsigned long) number % ULONG_MAX;
    printf("ULONG_MAX=%lu, number=%lu, result=%lu\n",
    ULONG_MAX, number, result);
    return 0;
    }

    Save it to a file, compile it, and run it. If the output looks ok,
    there may be some odd problem in your original code. If the problem
    persists, post the exact output that you get. Be sure to
    cut-and-paste it; don't attempt to re-type it.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 20, 2005
    #2
    1. Advertising

  3. ccwork

    ccwork Guest

    Keith Thompson wrote:
    > "ccwork" <> writes:
    > > Is the following codes Standard C?
    > >
    > > unsigned long number = ULONG_MAX;
    > > unsigned long result = 0;
    > >
    > > result = (unsigned long) number % ULONG_MAX;
    > > printf("ULONG_MAX=%lu, number=%lu, result=%lu\n", ULONG_MAX,

    number,
    > > result);
    > >
    > > My compiler (VC++ if you want to know), in debug mode, give:
    > > ULONG_MAX=4294967295, number3=4294967295, result3=0
    > >
    > > However, in release mode, it gives:
    > > ULONG_MAX=4294967295, number3=4294967295, result3=4294967295
    > >
    > > I don't know if the code trigger undefined behaviour or it is

    the
    > > compiler bug.

    >
    > It looks like it could be a compiler bug, but it's hard to be sure
    > since what you posted either isn't exactly your actual code, or isn't
    > your actual output. The printf statement has "number=" and

    "result=",
    > but the output you showed us has "number3=" and "result3=". It's
    > impossible to tell what other subtle differences there might be that
    > could explain the discrepancy.


    It is typo.

    > Also, the cast is superfluous; number is already of type unsigned
    > long, so casting it is unnecessary (unless it's necessary to trigger
    > the compiler bug).
    >
    > Here's a complete self-contained program (I've left the cast in

    place):
    >
    > #include <stdio.h>
    > #include <limits.h>
    > int main(void)
    > {
    > unsigned long number = ULONG_MAX;
    > unsigned long result = 0;
    >
    > result = (unsigned long) number % ULONG_MAX;
    > printf("ULONG_MAX=%lu, number=%lu, result=%lu\n",
    > ULONG_MAX, number, result);
    > return 0;
    > }
    >
    > Save it to a file, compile it, and run it. If the output looks ok,
    > there may be some odd problem in your original code. If the problem
    > persists, post the exact output that you get. Be sure to
    > cut-and-paste it; don't attempt to re-type it.


    I try. In debug mode the result is:
    ULONG_MAX=4294967295, number=4294967295, result=0

    in release mode:
    ULONG_MAX=4294967295, number=4294967295, result=4294967295
     
    ccwork, Apr 20, 2005
    #3
  4. "ccwork" <> writes:
    > Keith Thompson wrote:

    [snip]
    >> Here's a complete self-contained program (I've left the cast in place):
    >>
    >> #include <stdio.h>
    >> #include <limits.h>
    >> int main(void)
    >> {
    >> unsigned long number = ULONG_MAX;
    >> unsigned long result = 0;
    >>
    >> result = (unsigned long) number % ULONG_MAX;
    >> printf("ULONG_MAX=%lu, number=%lu, result=%lu\n",
    >> ULONG_MAX, number, result);
    >> return 0;
    >> }
    >>
    >> Save it to a file, compile it, and run it. If the output looks ok,
    >> there may be some odd problem in your original code. If the prnoblem
    >> persists, post the exact output that you get. Be sure to
    >> cut-and-paste it; don't attempt to re-type it.

    >
    > I try. In debug mode the result is:
    > ULONG_MAX=4294967295, number=4294967295, result=0
    >
    > in release mode:
    > ULONG_MAX=4294967295, number=4294967295, result=4294967295


    Interesting. It does look like a compiler error. (The debug mode
    output looks correct.)

    I suggest posting to a system-specific newsgroup, probably
    comp.os.ms-windows.programmer or one of the microsoft.* groups.
    Specify exactly what version of the compiler (VC++, you said) you're
    using. Maybe somebody else with the same version can try it; it could
    be either a compiler bug or something specific to your system.
    Examining the generated assembly code could also be useful (though of
    course it's off-topic here).

    You might also try it without the cast, and with unsigned int and
    UINT_MAX rather than unsigned long and ULONG_MAX.

    If it turns out to be a compiler bug, getting support from Microsoft
    is left as an exercise.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
     
    Keith Thompson, Apr 20, 2005
    #4
  5. On 20 Apr 2005 02:04:45 -0700, ccwork
    <> wrote:

    > Keith Thompson wrote:
    >>
    >> Here's a complete self-contained program (I've left the cast in
    >> place):
    >>
    >> #include <stdio.h>
    >> #include <limits.h>
    >> int main(void)
    >> {
    >> unsigned long number = ULONG_MAX;
    >> unsigned long result = 0;
    >>
    >> result = (unsigned long) number % ULONG_MAX;
    >> printf("ULONG_MAX=%lu, number=%lu, result=%lu\n",
    >> ULONG_MAX, number, result);
    >> return 0;
    >> }
    >>
    >> Save it to a file, compile it, and run it. If the output looks ok,
    >> there may be some odd problem in your original code. If the problem
    >> persists, post the exact output that you get. Be sure to
    >> cut-and-paste it; don't attempt to re-type it.

    >
    > I try. In debug mode the result is:
    > ULONG_MAX=4294967295, number=4294967295, result=0
    >
    > in release mode:
    > ULONG_MAX=4294967295, number=4294967295, result=4294967295


    It's a compiler optimisation bug of some sort. I just tried it with
    VC6:

    Default (no) optimisation:

    > cl 1.c
    > 1.exe

    ULONG_MAX=4294967295, number=4294967295, result=0

    Maximum optimisation:

    > cl /Ox 1.c
    > 1.exe

    ULONG_MAX=4294967295, number=4294967295, result=4294967295

    The actual one which does it is /Og ("enable global optimisation"), the
    other optimisation switches seem to be OK (on my machine).

    Report it to MS, and/or ask in a MS newsgroup. If you want help with
    it, email me privately (it's not on-topic for comp.lang.c, but I'm
    reporting here so others know to stop looking, I've crossposted and set
    followups to comp.os.ms-windows.programmer.misc where it's probably more
    on-topic).

    Chris C
     
    Chris Croughton, Apr 20, 2005
    #5
  6. ccwork wrote:
    > ...
    > I try. In debug mode the result is:
    > ULONG_MAX=4294967295, number=4294967295, result=0
    >
    > in release mode:
    > ULONG_MAX=4294967295, number=4294967295, result=4294967295
    > ...


    Definitely a compiler bug. If you try this

    unsigned long foo(unsigned long number)
    {
    return number % ULONG_MAX;
    }

    compile this in Release configuration (i.e. optimizations enabled) the
    resultant code for this function will look as follows

    004010C0 mov eax,dword ptr [esp+4]

    In C this is equivalent to a simple

    unsigned long foo(unsigned long number)
    {
    return number;
    }

    i.e. the compiler does not even try to calculate the remainder, but
    assumes instead that any 'unsigned long' value remains unchanged by the
    above expression, which is not true.

    A quick experiment shows that the compiler makes the same erroneous
    assumption about 'unsigned int' values in 'number % UINT_MAX' expression.

    --
    Best regards,
    Andrey Tarasevich
     
    Andrey Tarasevich, Apr 21, 2005
    #6
    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. victor goban
    Replies:
    5
    Views:
    698
    rossum
    Aug 19, 2004
  2. victor goban
    Replies:
    1
    Views:
    412
    Ioannis Vranos
    Aug 31, 2004
Loading...

Share This Page