locked
Sign-extended operand warning

    Question

  • I'm compiling some older C# code (perhaps C# 1.0) with the C# 2.0 compiler and get a warning I'd like to remedy:

     

    long chk = 0;

    int i = 0; // expected to hold a character value (8 sig bits, possibly negative)

    chk = chk << 8 | i;

     

    warning CS0675: Bitwise-or operator used on a sign-extended operand; consider casting to a smaller unsigned type first

     

    This is a gross distillation of the original code.  I'm a little paranoid about the bit arrangement in chk (it is switch statement expression comparing against bit patterns) so I don't want to rewrite too much of this--I just am looking for a way to make the compiler not emit a warning (and I can't use #pragma warning as that is not compat with .NET CF 1.0).  I tried casting away the problem, to no avail.

     

    TIA,
    Brian

     

     

     

    Friday, March 21, 2008 3:48 PM

Answers

  • I would cast i to (uint), which makes the warning go away. Since it only has 8 significant bits, this wouldn't cause any problems, unless the sign bit does...

     

    long chk = 0;

    int i = 0; // expected to hold a character value (8 sig bits, possibly negative)

    chk = chk << 8 | (uint)i;

     

    Friday, March 21, 2008 4:09 PM

All replies

  • I would cast i to (uint), which makes the warning go away. Since it only has 8 significant bits, this wouldn't cause any problems, unless the sign bit does...

     

    long chk = 0;

    int i = 0; // expected to hold a character value (8 sig bits, possibly negative)

    chk = chk << 8 | (uint)i;

     

    Friday, March 21, 2008 4:09 PM
  •  

    That did it. Thanks.
    Friday, March 21, 2008 4:13 PM
  • Cast the values to ulong and uint before the expression. That way you avoid the warning:

            long chk = 0;

            int i = 0; // expected to hold a character value (8 sig bits, possibly negative)

            ulong _chk = (ulong)chk;
            uint _i = (uint)i;
            chk = (long)(_chk << 8 | _i);

    Friday, March 21, 2008 5:51 PM
  •  DavidArno wrote:
    Cast the values to ulong and uint before the expression. That way you avoid the warning:

            long chk = 0;

            int i = 0; // expected to hold a character value (8 sig bits, possibly negative)

            ulong _chk = (ulong)chk;
            uint _i = (uint)i;
            chk = (long)(_chk << 8 | _i);


    This does change the data types, which should be avoided to prevent side-effects. We don't know what the rest of the code looks like, so changing data types for variables could be risky business...

    Friday, March 21, 2008 8:30 PM
  • Hence my trepidation Phillipe.  Taking the warning literally turned out to be the right path, but at first glance I wasn't so sure.  Here's the original code in all its gory.  Pretty wacky stuff.

     

    Code Snippet

    long chk = 0;

    while (srcCount < 4)

    {

    int i = is_Renamed.ReadByte();

    if (i == - 1)

    break;

    chk = (chk << 8) | i;

    srcBuf[srcCount++] = (char) i;

    }

    if (srcCount == 4)

    {

    switch (chk)

    {

    case 0x00000FEFF:

    enc = "UTF-32BE";

    srcCount = 0;

    break;

    // TODO

    // case (int) SupportClass.Identity(0x0FFFE0000):

    // enc = "UTF-32LE";

    // srcCount = 0;

    // break;

    case 0x0FFFE0000:

    enc = "UTF-32LE";

    srcCount = 0;

    break;

    case 0x03c:

    enc = "UTF-32BE";

    srcBuf[0] = '<';

    srcCount = 1;

    break;

    case 0x03c000000:

    enc = "UTF-32LE";

    srcBuf[0] = '<';

    srcCount = 1;

    break;

    case 0x0003c003f:

    enc = "UTF-16BE";

    srcBuf[0] = '<';

    srcBuf[1] = '?';

    srcCount = 2;

    break;

    case 0x03c003f00:

    enc = "UTF-16LE";

    srcBuf[0] = '<';

    srcBuf[1] = '?';

    srcCount = 2;

    break;

    case 0x03c3f786d:

    while (true)

    {

    int i = is_Renamed.ReadByte();

    if (i == - 1)

    break;

    srcBuf[srcCount++] = (char) i;

    if (i == '>')

    {

    string s = new string(srcBuf, 0, srcCount);

    int i0 = s.IndexOf("encoding");

    if (i0 != - 1)

    {

    while (s[i0] != '"' && s[i0] != '\'')

    i0++;

    char deli = s[i0++];

    //UPGRADE_WARNING: Method 'java.lang.String.indexOf' was converted to 'string.IndexOf' which may throw an exception. 'ms-help://MS.VSCC.2003/commoner/redir/redirect.htm?keyword="jlca1101"'

    int i1 = s.IndexOf((System.Char) deli, i0);

    enc = s.Substring(i0, (i1) - (i0));

    }

    break;

    }

    }

    goto default;

    default:

    if ((chk & 0x0ffff0000) == 0x0FEFF0000)

    {

    enc = "UTF-16BE";

    srcBuf[0] = (char) ((srcBuf[2] << 8) | srcBuf[3]);

    srcCount = 1;

    }

    else if ((chk & 0x0ffff0000) == 0x0fffe0000)

    {

    enc = "UTF-16LE";

    srcBuf[0] = (char) ((srcBuf[3] << 8) | srcBuf[2]);

    srcCount = 1;

    }

    else if ((chk & 0x0ffffff00) == 0x0EFBBBF00)

    {

    enc = "UTF-8";

    srcBuf[0] = srcBuf[3];

    srcCount = 1;

    }

    break;

    }

     

     

    Friday, March 21, 2008 8:35 PM
  • Pretty heavy stuff Brian... (you even had me looking up the word "trepidation" ... not that obvious if English is not your native language )

    Friday, March 21, 2008 8:44 PM