digitalmars.D.bugs - Bug in pointer arithmetics
- Niko Korhonen (26/26) Mar 07 2005 Consider the following code, meant to change the endian-ness of the
- Derek Parnell (44/77) Mar 07 2005 If I might suggest an alternate method, without using pointers, and a bi...
- Niko Korhonen (7/9) Mar 07 2005 I wasn't trying to create the most elegant or the most effective byte
- zwang (21/54) Mar 07 2005 This seems to be a bug of casting...
- Thomas Kuehne (11/31) Mar 17 2005 -----BEGIN PGP SIGNED MESSAGE-----
- Ben Hinkle (5/31) Mar 07 2005 Interestingly enough it looks like it works with
Consider the following code, meant to change the endian-ness of the argument: uint flip(uint x) { // The initial value shouldn't matter uint inverted = 555; ubyte* target = cast(ubyte*)&inverted; ubyte* source = cast(ubyte*)&x; // printf("source: %x\ntarget: %x\n", // cast(uint)source, cast(uint)target); target[0] = source[3]; target[1] = source[2]; target[2] = source[1]; target[3] = source[0]; return inverted; } void main() { uint num = 1; printf("Original: %u flipped %u\n", num, flip(num)); } This code always prints 555 for 'flipped' with DMD 0.115. But when you uncomment the printf line, it works as it should. When compiling with -O, it seems to set every byte of 'inverted' to 0x01. It would appear that the compiler thinks that nothing is done with the argument 'inverted' during the function and returns it's initial value.
Mar 07 2005
On Mon, 07 Mar 2005 14:51:22 +0200, Niko Korhonen wrote:Consider the following code, meant to change the endian-ness of the argument: uint flip(uint x) { // The initial value shouldn't matter uint inverted = 555; ubyte* target = cast(ubyte*)&inverted; ubyte* source = cast(ubyte*)&x; // printf("source: %x\ntarget: %x\n", // cast(uint)source, cast(uint)target); target[0] = source[3]; target[1] = source[2]; target[2] = source[1]; target[3] = source[0]; return inverted; } void main() { uint num = 1; printf("Original: %u flipped %u\n", num, flip(num)); } This code always prints 555 for 'flipped' with DMD 0.115. But when you uncomment the printf line, it works as it should. When compiling with -O, it seems to set every byte of 'inverted' to 0x01. It would appear that the compiler thinks that nothing is done with the argument 'inverted' during the function and returns it's initial value.If I might suggest an alternate method, without using pointers, and a bit more generic ... <code> import std.stdio; template ByteFlip(T) { T flip(T x) { union F { T num; ubyte[num.sizeof] b; } F o; F i; o.num = 255; // The initial value shouldn't matter i.num = x; foreach(int i,ubyte c; i.b) o.b[length-i-1] = c; return o.num; } } alias ByteFlip!(ubyte).flip flip; alias ByteFlip!(ushort).flip flip; alias ByteFlip!(uint).flip flip; alias ByteFlip!(ulong).flip flip; void main() { ubyte num_byte = 1; ushort num_short = 1; uint num_int = 1; ulong num_long = 1; writefln("Original: %d byte flipped %d", num_byte, flip(num_byte)); writefln("Original: %d short flipped %d", num_short, flip(num_short)); writefln("Original: %d int flipped %d", num_int, flip(num_int)); writefln("Original: %d long flipped %d", num_long, flip(num_long)); } </code> Seems to work regardless of -O switch. -- Derek Parnell Melbourne, Australia 8/03/2005 12:11:00 AM
Mar 07 2005
Derek Parnell wrote:If I might suggest an alternate method, without using pointers, and a bit more generic ...I wasn't trying to create the most elegant or the most effective byte flipping function possible, I was just coding for fun :) I can certainly work around this issue easily, but I still think there's something wrong in the compiler and it should be addressed. Also it seems that compiling my original example with -inline fixes the problem.
Mar 07 2005
This seems to be a bug of casting... Consider the following code: <code> uint f(){ uint r; uint* p = cast(uint*)&r; *p = 1; return r; } uint g(){ uint r; int* p = cast(int*)&r; *p = 1; return r; } void main(){ assert(f()==1); //OK assert(g()==1); //<-- Assertion Error } </code> Niko Korhonen wrote:Consider the following code, meant to change the endian-ness of the argument: uint flip(uint x) { // The initial value shouldn't matter uint inverted = 555; ubyte* target = cast(ubyte*)&inverted; ubyte* source = cast(ubyte*)&x; // printf("source: %x\ntarget: %x\n", // cast(uint)source, cast(uint)target); target[0] = source[3]; target[1] = source[2]; target[2] = source[1]; target[3] = source[0]; return inverted; } void main() { uint num = 1; printf("Original: %u flipped %u\n", num, flip(num)); } This code always prints 555 for 'flipped' with DMD 0.115. But when you uncomment the printf line, it works as it should. When compiling with -O, it seems to set every byte of 'inverted' to 0x01. It would appear that the compiler thinks that nothing is done with the argument 'inverted' during the function and returns it's initial value.
Mar 07 2005
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 zwang schrieb am Mon, 07 Mar 2005 21:42:55 +0800:This seems to be a bug of casting... Consider the following code: <code> uint f(){ uint r; uint* p = cast(uint*)&r; *p = 1; return r; } uint g(){ uint r; int* p = cast(int*)&r; *p = 1; return r; } void main(){ assert(f()==1); //OK assert(g()==1); //<-- Assertion Error } </code>Added to DStress as http://dstress.kuehne.cn/run/cast_22.d Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFCOaDK3w+/yD4P9tIRAm6oAKCZn2vVa5hb4QX1Zy/CGjWVq+y0WwCeMdzY oO/NnkeSHykwYj1kkCpb6J8= =yNPw -----END PGP SIGNATURE-----
Mar 17 2005
Interestingly enough it looks like it works with ubyte[] target = (cast(ubyte*)&inverted)[0..4]; ubyte[] source = (cast(ubyte*)&x)[0..4]; "Niko Korhonen" <niktheblak hotmail.com> wrote in message news:d0hio7$2bs6$1 digitaldaemon.com...Consider the following code, meant to change the endian-ness of the argument: uint flip(uint x) { // The initial value shouldn't matter uint inverted = 555; ubyte* target = cast(ubyte*)&inverted; ubyte* source = cast(ubyte*)&x; // printf("source: %x\ntarget: %x\n", // cast(uint)source, cast(uint)target); target[0] = source[3]; target[1] = source[2]; target[2] = source[1]; target[3] = source[0]; return inverted; } void main() { uint num = 1; printf("Original: %u flipped %u\n", num, flip(num)); } This code always prints 555 for 'flipped' with DMD 0.115. But when you uncomment the printf line, it works as it should. When compiling with -O, it seems to set every byte of 'inverted' to 0x01. It would appear that the compiler thinks that nothing is done with the argument 'inverted' during the function and returns it's initial value.
Mar 07 2005