Thread overview | ||||||||
---|---|---|---|---|---|---|---|---|
|
March 07, 2005 Bug in pointer arithmetics | ||||
---|---|---|---|---|
| ||||
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. |
March 07, 2005 Re: Bug in pointer arithmetics | ||||
---|---|---|---|---|
| ||||
Posted in reply to Niko Korhonen | 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 |
March 07, 2005 Re: Bug in pointer arithmetics | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | 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.
|
March 07, 2005 Re: Bug in pointer arithmetics | ||||
---|---|---|---|---|
| ||||
Posted in reply to Niko Korhonen | 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.
|
March 07, 2005 Re: Bug in pointer arithmetics | ||||
---|---|---|---|---|
| ||||
Posted in reply to Niko Korhonen | 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. |
March 17, 2005 Re: Bug in pointer arithmetics | ||||
---|---|---|---|---|
| ||||
Posted in reply to zwang | -----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----- |
Copyright © 1999-2021 by the D Language Foundation