Thread overview | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|
|
January 18, 2006 How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
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. |
January 19, 2006 Re: How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Stevenson | 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 |
January 19, 2006 Re: How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | 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)
|
January 19, 2006 Re: How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | 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.
|
January 19, 2006 Re: How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Stevenson | 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. |
January 19, 2006 Re: How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | 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... http://www.digitalmars.com/drn-bin/wwwnews?digitalmars.D.bugs/2153 --anders |
January 19, 2006 Re: How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
Posted in reply to Anders F Björklund | Anders F Björklund wrote: > BCS wrote: > >> >> >> Well maybe their should be one. > > > Don't hold your breath, though... > > http://www.digitalmars.com/drn-bin/wwwnews?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. |
January 20, 2006 Re: How to fix this warning problem: | ||||
---|---|---|---|---|
| ||||
Posted in reply to BCS | 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... >> >> http://www.digitalmars.com/drn-bin/wwwnews?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; } } |
Copyright © 1999-2021 by the D Language Foundation