Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

64-bit puzzle

0 views
Skip to first unread message

karpo...@gmail.com

unread,
Feb 3, 2007, 1:05:23 PM2/3/07
to
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.

karpo...@gmail.com

unread,
Feb 3, 2007, 1:19:03 PM2/3/07
to
Discrepancy is admitted:
ptr = ptr + (a + b); - Invalid pointer value on 64-bit platform
printf("%i\n", *ptr); - Access violation on 64-bit platform

Kai-Uwe Bux

unread,
Feb 3, 2007, 1:36:57 PM2/3/07
to
karpo...@gmail.com 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

unread,
Feb 3, 2007, 2:14:06 PM2/3/07
to
Kai-Uwe Bux wrote:

> karpo...@gmail.com 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].

Alf P. Steinbach

unread,
Feb 3, 2007, 2:28:36 PM2/3/07
to
* Kai-Uwe Bux:

> karpo...@gmail.com 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?

Kai-Uwe Bux

unread,
Feb 3, 2007, 3:07:33 PM2/3/07
to
Alf P. Steinbach wrote:

> * Kai-Uwe Bux:
>> karpo...@gmail.com 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

Pan

unread,
Feb 3, 2007, 3:56:39 PM2/3/07
to
karpo...@gmail.com 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

karp...@list.ru

unread,
Feb 6, 2007, 12:00:24 PM2/6/07
to
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

0 new messages