www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to fix this warning problem:

reply Alex Stevenson <ans104 cs.york.ac.uk> writes:
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) & 



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.
Jan 18 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
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
parent reply BCS <BCS_member pathlink.com> writes:
Regan Heath wrote:
 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

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)
Jan 19 2006
parent reply Alex Stevenson <ans104 cs.york.ac.uk> writes:
BCS wrote:
 Regan Heath wrote:
 
 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

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
parent reply BCS <BCS_member pathlink.com> writes:
Alex Stevenson wrote:
 BCS 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 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.

Well maybe their should be one.
Jan 19 2006
parent reply =?ISO-8859-15?Q?Anders_F_Bj=F6rklund?= <afb algonet.se> writes:
BCS 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 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.

Well maybe their should be one.

Don't hold your breath, though... digitalmars.D.bugs/2153 --anders
Jan 19 2006
parent reply BCS <BCS_member pathlink.com> writes:
Anders F Björklund wrote:
 BCS wrote:
 
 Well maybe their should be one.

Don't hold your breath, though... digitalmars.D.bugs/2153 --anders

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.
Jan 19 2006
parent anon <anon_member pathlink.com> writes:
In article <dqos5c$av8$2 digitaldaemon.com>, BCS says...
Anders F Björklund wrote:
 BCS wrote:
 
 Well maybe their should be one.

Don't hold your breath, though... digitalmars.D.bugs/2153 --anders

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.

yes something like the following should work: ushort bswap(ushort val) { asm { naked; xchg AL,AH; ret; } }
Jan 20 2006