Krautkanal.com

Veröffentlicht am 2016-05-10 15:55:16 in /prog/

/prog/ 8795: Explanation A programmer wants to shift a pointer at...

subburam Avatar
subburam:#8795

Explanation

A programmer wants to shift a pointer at a certain number of bytes. This code will execute correctly in Win32 mode because the pointer size is the same as that of the long type. But if we compile a 64-bit version of the program, the pointer will become 64-bit, and casting it to long will cause the loss of the higher bits.

Note. Linux uses a different data model. In 64-bit Linux programs, the 'long' type is 64-bit too, but it's still a bad idea to use 'long' to store pointers there. First, such code tends to get into Windows applications quite often, where it becomes incorrect. Second, there are special types whose very names suggest that they can store pointers - for example, intptr_t. Using such types makes the program clearer.

In the example above, we can see a classic error which occurs in 64-bit programs. It should be said right off that there are lots of other errors, too, awaiting programmers in their way of 64-bit software development. But it is the writing of a pointer into a 32-bit integer variable that's the most widespread and insidious issue.

Figure 1. A) 32-bit program. B) 64-bit pointer refers to an object that is located in the lower addresses. C) 64-bit pointer is damaged.

More: https://yadi.sk/i/zKHIOS84r87nk (part 6)

dwardt Avatar
dwardt:#8796

Lange sind in Windows auch unter 64 Bit bloß 4 Byte groß?

robinlayfield Avatar
robinlayfield:#8797

Pointer nach irgendwas kasten ist undefiniert. Okeedaswar ales.

rohan30993 Avatar
rohan30993:#8798

>>8795
Da macht man einen grundsätzlichen Fehler. Man soll entweder:

1. den Offset (iStep in diesem Fall) nicht in Bytes definieren, sondern in Elementen des Arrays, dann kann man ohne jede Konversion img+=iStep schreiben. Oder:

2. Man konvertiert den Zeiger nach Zeiger, z.B mit (uint8_t *), dann wird die Größe automatisch richtig

Für Byte-Offsets soll man übrigens size_t, ssize_t oder ptrdiff_t nutzen - diese Typen haben auch automatisch die richtige Größe für Zeigerarithmetik.

joshkennedy Avatar
joshkennedy:#8820

long long ist bekannt, ja?