64-bit puzzle

Discussion in 'C++' started by karpov2007@gmail.com, Feb 3, 2007.

  1. Guest

    The computer industry is changing, and 64-bit technology is the next,
    inevitable step.
    Look at sample.

    int main(int, const char **) {
    int a = -2;
    unsigned b = 1;
    int array[5] = { 1, 2, 3, 4, 5 };
    int *ptr = array + 3;
    ptr = ptr + (a + b); //Access violation on 64-bit platform
    printf("%i\n", *ptr);
    return 0;
    }

    Do you know why this code does not work on 64-bit system? Do you
    assured, what no similar errors founds in your code? Do you know other
    typical errors reduce to down state C++ code on 64-bit platforms? If
    is not present then visit site www.Viva64.com.
    On this site you can find plenty information, devoted to programming
    of 64-bit systems. And also static analyzer Viva64 for detects
    multitude 64-bit portability issues.
    , Feb 3, 2007
    #1
    1. Advertising

  2. Guest

    Discrepancy is admitted:
    ptr = ptr + (a + b); - Invalid pointer value on 64-bit platform
    printf("%i\n", *ptr); - Access violation on 64-bit platform
    , Feb 3, 2007
    #2
    1. Advertising

  3. Kai-Uwe Bux Guest

    wrote:

    > The computer industry is changing, and 64-bit technology is the next,
    > inevitable step.
    > Look at sample.
    >
    > int main(int, const char **) {
    > int a = -2;
    > unsigned b = 1;
    > int array[5] = { 1, 2, 3, 4, 5 };
    > int *ptr = array + 3;
    > ptr = ptr + (a + b); //Access violation on 64-bit platform
    > printf("%i\n", *ptr);
    > return 0;
    > }
    >
    > Do you know why this code does not work on 64-bit system?


    For the same reason it does not work on 32 bit systems: the sum a+b is
    subject to the conversion rules. Since b is of unsigned type, a is
    converted to unsigned type [5/9]. This is undefined behavior for negative
    values of a [5/5]. If it appears to work on your platform, then it was just
    by coincidence.


    > Do you assured, what no similar errors founds in your code?


    Yes.


    > Do you know other
    > typical errors reduce to down state C++ code on 64-bit platforms?


    No. However, I would surely hope that the above does not qualify as a
    typical mistake. Also, it is a mistake on any platform, not just 64 bit
    platforms.

    > If is not present then visit site www.Viva64.com.


    This sentence does not parse.

    > On this site you can find plenty information, devoted to programming
    > of 64-bit systems. And also static analyzer Viva64 for detects
    > multitude 64-bit portability issues.


    Oops, are you a spammer by any chance?


    Best

    Kai-Uwe Bux
    Kai-Uwe Bux, Feb 3, 2007
    #3
  4. Kai-Uwe Bux Guest

    Kai-Uwe Bux wrote:

    > wrote:
    >
    >> The computer industry is changing, and 64-bit technology is the next,
    >> inevitable step.
    >> Look at sample.
    >>
    >> int main(int, const char **) {
    >> int a = -2;
    >> unsigned b = 1;
    >> int array[5] = { 1, 2, 3, 4, 5 };
    >> int *ptr = array + 3;
    >> ptr = ptr + (a + b); //Access violation on 64-bit platform
    >> printf("%i\n", *ptr);
    >> return 0;
    >> }
    >>
    >> Do you know why this code does not work on 64-bit system?

    >
    > For the same reason it does not work on 32 bit systems: the sum a+b is
    > subject to the conversion rules. Since b is of unsigned type, a is
    > converted to unsigned type [5/9]. This is undefined behavior for negative
    > values of a [5/5]. If it appears to work on your platform, then it was
    > just by coincidence.


    Oops, turns out I misidentified the source of undefined behavior: a+b is not
    undefined because of [4.7/2] (sometimes there are more guarantees in the
    standard than I am used to expect:). So what should happen is a+b is
    evaluated to unsigned(-2) + unsigned(1), which is the same as unsigned(-1).
    Then this huge number is added to ptr. The undefined behavior actually
    stems from [5.7/5].


    >
    >> Do you assured, what no similar errors founds in your code?

    >
    > Yes.
    >
    >
    >> Do you know other
    >> typical errors reduce to down state C++ code on 64-bit platforms?

    >
    > No. However, I would surely hope that the above does not qualify as a
    > typical mistake. Also, it is a mistake on any platform, not just 64 bit
    > platforms.
    >
    >> If is not present then visit site www.Viva64.com.

    >
    > This sentence does not parse.
    >
    >> On this site you can find plenty information, devoted to programming
    >> of 64-bit systems. And also static analyzer Viva64 for detects
    >> multitude 64-bit portability issues.

    >
    > Oops, are you a spammer by any chance?
    >
    >
    > Best
    >
    > Kai-Uwe Bux
    Kai-Uwe Bux, Feb 3, 2007
    #4
  5. * Kai-Uwe Bux:
    > wrote:
    >
    >> The computer industry is changing, and 64-bit technology is the next,
    >> inevitable step.
    >> Look at sample.
    >>
    >> int main(int, const char **) {
    >> int a = -2;
    >> unsigned b = 1;
    >> int array[5] = { 1, 2, 3, 4, 5 };
    >> int *ptr = array + 3;
    >> ptr = ptr + (a + b); //Access violation on 64-bit platform
    >> printf("%i\n", *ptr);
    >> return 0;
    >> }
    >>
    >> Do you know why this code does not work on 64-bit system?

    >
    > For the same reason it does not work on 32 bit systems: the sum a+b is
    > subject to the conversion rules. Since b is of unsigned type, a is
    > converted to unsigned type [5/9]. This is undefined behavior for negative
    > values of a [5/5].


    I'd say "chapter and verse, please", except that seemingly you provided
    that -- except that AFAICS the references given don't correspond to
    anything in the standard.

    Anyway, the signed->unsigned conversion is well-defined, §4.5/1 -> §4.7/2.

    (a + b) then yields -1 + 2^n, where n is the number of value
    representation bits in 'unsigned', and the rhs of the assignment ends up
    with an undefined value, which yields Undefined Behavior when assigned
    to 'ptr'.


    > If it appears to work on your platform, then it was just
    > by coincidence.


    Yep.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
    Alf P. Steinbach, Feb 3, 2007
    #5
  6. Kai-Uwe Bux Guest

    Alf P. Steinbach wrote:

    > * Kai-Uwe Bux:
    >> wrote:
    >>
    >>> The computer industry is changing, and 64-bit technology is the next,
    >>> inevitable step.
    >>> Look at sample.
    >>>
    >>> int main(int, const char **) {
    >>> int a = -2;
    >>> unsigned b = 1;
    >>> int array[5] = { 1, 2, 3, 4, 5 };
    >>> int *ptr = array + 3;
    >>> ptr = ptr + (a + b); //Access violation on 64-bit platform
    >>> printf("%i\n", *ptr);
    >>> return 0;
    >>> }
    >>>
    >>> Do you know why this code does not work on 64-bit system?

    >>
    >> For the same reason it does not work on 32 bit systems: the sum a+b is
    >> subject to the conversion rules. Since b is of unsigned type, a is
    >> converted to unsigned type [5/9]. This is undefined behavior for negative
    >> values of a [5/5].

    >
    > I'd say "chapter and verse, please", except that seemingly you provided
    > that -- except that AFAICS the references given don't correspond to
    > anything in the standard.


    They do:

    [5/9]:
    Many binary operators that expect operands of arithmetic or enumeration type
    cause conversions and yield result types in a similar way. The purpose is
    to yield a common type, which is also the type of the result. This pattern
    is called the usual arithmetic conversions, which are defined as follows:
    [...]
    ? Otherwise, if either operand is unsigned, the other shall be converted to
    unsigned.

    [5/5]:
    If during the evaluation of an expression, the result is not mathematically
    defined or not in the range of representable values for its type, the
    behavior is undefined, unless such an expression is a constant expression
    (5.19), in which case the program is ill-formed.


    Probably the trickyness is that all of these come even before [5.1].

    > Anyway, the signed->unsigned conversion is well-defined, §4.5/1 -> §4.7/2.


    You are correct on that one, see my self-correction elsethread.

    > (a + b) then yields -1 + 2^n, where n is the number of value
    > representation bits in 'unsigned', and the rhs of the assignment ends up
    > with an undefined value, which yields Undefined Behavior when assigned
    > to 'ptr'.


    True, I also realized that afterwards.


    >> If it appears to work on your platform, then it was just
    >> by coincidence.

    >
    > Yep.



    Thanks

    Kai-Uwe Bux
    Kai-Uwe Bux, Feb 3, 2007
    #6
  7. Pan Guest

    wrote:

    > ptr = ptr + (a + b); //Access violation on 64-bit platform
    > printf("%i\n", *ptr);


    I found the same problem on the code I'm working on.
    It's because (a+b) is unsigned and usually they're still 32 bits wide,
    but the pointers are 64 bits wide. You're actually ADDING a big
    (>4billions) number rather than subtracting a small amount.
    This worked just by coincidence on most older architectures because
    pointers and unsigned were the same bits wide (they're usually both 32).

    --
    Marco
    Pan, Feb 3, 2007
    #7
  8. Guest

    By the way, the similar example uses at lectures Kang Su Gatlin. Kang
    Su Gatlin is a program manager on the Visual C++ team and recently
    spoke as part of the Route 64 Training Tour. Here it is possible to
    look its small performance: http://channel9.msdn.com/ShowPost.aspx?PostID=53939
    , Feb 6, 2007
    #8
    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. Replies:
    3
    Views:
    1,714
    Timothy Bendfelt
    Jan 19, 2007
  2. Replies:
    9
    Views:
    938
    Juha Nieminen
    Aug 22, 2007
  3. Steven G. Johnson

    a bit of a puzzle

    Steven G. Johnson, Mar 9, 2008, in forum: C Programming
    Replies:
    13
    Views:
    600
    Richard
    Mar 10, 2008
  4. Rick Dearman

    A bit of fun. A programming puzzle to be done in C.

    Rick Dearman, Jan 3, 2009, in forum: C Programming
    Replies:
    17
    Views:
    566
  5. Jeff.M
    Replies:
    6
    Views:
    162
    Lasse Reichstein Nielsen
    May 4, 2009
Loading...

Share This Page