digitalmars.D.learn - How to fix this warning problem:
- Alex Stevenson (24/25) Jan 18 2006 I have a quick-and-dirty inplace endianness conversion function for usho...
- Regan Heath (40/66) Jan 18 2006 I believe the problem occurs because the operations &, |, >>> and <<
- BCS (4/86) Jan 19 2006 Isn't there a byte swap intrinsic function (IIRC it uses 32bit values bu...
- Alex Stevenson (6/95) Jan 19 2006 I use bswap from std.intrinsic for 32-bit values, but there is no
- BCS (3/14) Jan 19 2006 Well maybe their should be one.
- =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= (4/15) Jan 19 2006 Don't hold your breath, though...
I have a quick-and-dirty inplace endianness conversion function for ushorts: ushort ConvertEndian(inout ushort input) { version(LittleEndian) { return (input = ((input & 0xff00) >>> 8) | ((input & 0x00ff) << 8)); } else { return input; } } Compiling with -w on DMD always gives the warning: warning - util.d(40): implicit conversion of expression ((cast(int)(input) & 65280) >> 8 | (cast(int)(input) & 255) << 8) of type int to ushort can cause loss of data I've tried inserting cast(ushort) everywhere I could - but the warning stays... Even when I insert casts before every ( and constant: warning - util.d(40): implicit conversion of expression (cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) & 65280)255) << 8)) of type int to ushort can cause loss of data Is there something I'm overlooking here? I'd like to use -w as I've been caught out by 'no return' problems a couple of times.8) | cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) &
Jan 18 2006
On Wed, 18 Jan 2006 17:31:06 +0000, Alex Stevenson <ans104 cs.york.ac.uk> wrote:I have a quick-and-dirty inplace endianness conversion function for ushorts: ushort ConvertEndian(inout ushort input) { version(LittleEndian) { return (input = ((input & 0xff00) >>> 8) | ((input & 0x00ff) << 8)); } else { return input; } } Compiling with -w on DMD always gives the warning: warning - util.d(40): implicit conversion of expression ((cast(int)(input) & 65280) >> 8 | (cast(int)(input) & 255) << 8) of type int to ushort can cause loss of data I've tried inserting cast(ushort) everywhere I could - but the warning stays... Even when I insert casts before every ( and constant: warning - util.d(40): implicit conversion of expression (cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) & 65280) >>> 8) | cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) & 255) << 8)) of type int to ushort can cause loss of data Is there something I'm overlooking here? I'd like to use -w as I've been caught out by 'no return' problems a couple of times.I believe the problem occurs because the operations &, |, >>> and << promote the operands to 'int' and give an 'int' result, therefore passing or assigning the result to a ushort is and "implicit" conversion from int to ushort. You have to cast the results of each operation to ushort to fix it, eg. ushort ConvertEndian(inout ushort input) { version(LittleEndian) { return (input = cast(ushort)(cast(ushort)(cast(ushort)(input & 0xff00) >>> 8) | cast(ushort)(cast(ushort)(input & 0x00ff) << 8))); } else { return input; } } or, perhaps just use an int, eg. ushort ConvertEndian(inout ushort input) { version(LittleEndian) { int i = input; i = (((i & 0xff00) >>> 8) | ((i & 0x00ff) << 8)); return cast(ushort)i; } else { return input; } } Why does "ushort & ushort" require both operands promoted to int? Why do it? Regan
Jan 18 2006
Regan Heath wrote:On Wed, 18 Jan 2006 17:31:06 +0000, Alex Stevenson <ans104 cs.york.ac.uk> wrote:Isn't there a byte swap intrinsic function (IIRC it uses 32bit values but a x86 ASM has an XCHG op that does exactly what you are looking for, maybe this should be added to std.intrinsic)I have a quick-and-dirty inplace endianness conversion function for ushorts: ushort ConvertEndian(inout ushort input) { version(LittleEndian) { return (input = ((input & 0xff00) >>> 8) | ((input & 0x00ff) << 8)); } else { return input; } } Compiling with -w on DMD always gives the warning: warning - util.d(40): implicit conversion of expression ((cast(int)(input) & 65280) >> 8 | (cast(int)(input) & 255) << 8) of type int to ushort can cause loss of data I've tried inserting cast(ushort) everywhere I could - but the warning stays... Even when I insert casts before every ( and constant: warning - util.d(40): implicit conversion of expression (cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) & 65280) >>> 8) | cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) & 255) << 8)) of type int to ushort can cause loss of data Is there something I'm overlooking here? I'd like to use -w as I've been caught out by 'no return' problems a couple of times.I believe the problem occurs because the operations &, |, >>> and << promote the operands to 'int' and give an 'int' result, therefore passing or assigning the result to a ushort is and "implicit" conversion from int to ushort. You have to cast the results of each operation to ushort to fix it, eg. ushort ConvertEndian(inout ushort input) { version(LittleEndian) { return (input = cast(ushort)(cast(ushort)(cast(ushort)(input & 0xff00) >>> 8) | cast(ushort)(cast(ushort)(input & 0x00ff) << 8))); } else { return input; } } or, perhaps just use an int, eg. ushort ConvertEndian(inout ushort input) { version(LittleEndian) { int i = input; i = (((i & 0xff00) >>> 8) | ((i & 0x00ff) << 8)); return cast(ushort)i; } else { return input; } } Why does "ushort & ushort" require both operands promoted to int? Why do it? Regan
Jan 19 2006
BCS wrote:Regan Heath wrote:I use bswap from std.intrinsic for 32-bit values, but there is no corresponding function for 16-bit values. Having done some low-level SCSI work, I find that 16-bit endianness conversions are pretty common and it doesn't make too much sense to be to have an intrinsic for 32-bit endianness swapping but not 16-bit.On Wed, 18 Jan 2006 17:31:06 +0000, Alex Stevenson <ans104 cs.york.ac.uk> wrote:Isn't there a byte swap intrinsic function (IIRC it uses 32bit values but a x86 ASM has an XCHG op that does exactly what you are looking for, maybe this should be added to std.intrinsic)I have a quick-and-dirty inplace endianness conversion function for ushorts: ushort ConvertEndian(inout ushort input) { version(LittleEndian) { return (input = ((input & 0xff00) >>> 8) | ((input & 0x00ff) << 8)); } else { return input; } } Compiling with -w on DMD always gives the warning: warning - util.d(40): implicit conversion of expression ((cast(int)(input) & 65280) >> 8 | (cast(int)(input) & 255) << 8) of type int to ushort can cause loss of data I've tried inserting cast(ushort) everywhere I could - but the warning stays... Even when I insert casts before every ( and constant: warning - util.d(40): implicit conversion of expression (cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) & 65280) >>> 8) | cast(int)cast(ushort)(cast(int)cast(ushort)(cast(int)(input) & 255) << 8)) of type int to ushort can cause loss of data Is there something I'm overlooking here? I'd like to use -w as I've been caught out by 'no return' problems a couple of times.I believe the problem occurs because the operations &, |, >>> and << promote the operands to 'int' and give an 'int' result, therefore passing or assigning the result to a ushort is and "implicit" conversion from int to ushort. You have to cast the results of each operation to ushort to fix it, eg. ushort ConvertEndian(inout ushort input) { version(LittleEndian) { return (input = cast(ushort)(cast(ushort)(cast(ushort)(input & 0xff00) >>> 8) | cast(ushort)(cast(ushort)(input & 0x00ff) << 8))); } else { return input; } } or, perhaps just use an int, eg. ushort ConvertEndian(inout ushort input) { version(LittleEndian) { int i = input; i = (((i & 0xff00) >>> 8) | ((i & 0x00ff) << 8)); return cast(ushort)i; } else { return input; } } Why does "ushort & ushort" require both operands promoted to int? Why do it? Regan
Jan 19 2006
Alex Stevenson wrote:BCS wrote:[...]Well maybe their should be one.Isn't there a byte swap intrinsic function (IIRC it uses 32bit values but a x86 ASM has an XCHG op that does exactly what you are looking for, maybe this should be added to std.intrinsic)I use bswap from std.intrinsic for 32-bit values, but there is no corresponding function for 16-bit values. Having done some low-level SCSI work, I find that 16-bit endianness conversions are pretty common and it doesn't make too much sense to be to have an intrinsic for 32-bit endianness swapping but not 16-bit.
Jan 19 2006
BCS wrote:Don't hold your breath, though... http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/2153 --andersWell maybe their should be one.Isn't there a byte swap intrinsic function (IIRC it uses 32bit values but a x86 ASM has an XCHG op that does exactly what you are looking for, maybe this should be added to std.intrinsic)I use bswap from std.intrinsic for 32-bit values, but there is no corresponding function for 16-bit values. Having done some low-level SCSI work, I find that 16-bit endianness conversions are pretty common and it doesn't make too much sense to be to have an intrinsic for 32-bit endianness swapping but not 16-bit.
Jan 19 2006
Anders F Björklund wrote:BCS wrote:x86 has it. http://download.intel.com/design/Pentium4/manuals/25366718.pdf look at 4.1 XCHG at about the middle of the table IIRC the high and low bytes in a 16 bit reg can be addressed as 8 bit regs.Well maybe their should be one.Don't hold your breath, though... http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/2153 --anders
Jan 19 2006
In article <dqos5c$av8$2 digitaldaemon.com>, BCS says...Anders F Björklund wrote:yes something like the following should work: ushort bswap(ushort val) { asm { naked; xchg AL,AH; ret; } }BCS wrote:x86 has it. http://download.intel.com/design/Pentium4/manuals/25366718.pdf look at 4.1 XCHG at about the middle of the table IIRC the high and low bytes in a 16 bit reg can be addressed as 8 bit regs.Well maybe their should be one.Don't hold your breath, though... http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/2153 --anders
Jan 20 2006