紫雨轩 .Net, DNGuard HVM , .Net VMProtect

DNGuard HVM - Advanced .NET Code Protection Technology

导航

.Net中的数字类型四则运算的有趣问题

看看下面的代码:
     sbyte sba, sbb,sbv;
            sba = 1;
            sbb = 2;
            sbv = sba + sbb;

            byte ba, bb, bv;
            ba = 1;
            bb = 2;
            bv = ba + bb;

            short sa, sb, sv;
            sa = 1;
            sb = 2;
            sv = sa + sb;

            ushort usa, usb, usv;
            usa = 1;
            usb = 2;
            usv = usa + usb;

            MessageBox.Show(string.Format("{0},{1},{2},{3}", sbv, bv, sv, usv));
你觉得这段代码能否正确执行?结果会怎样?

用VS2005打开项目测试一下你就会发现,这段代码会出现编译错误.
正确的代码应该如下:           
            sbyte sba, sbb,sbv;
            sba = 1;
            sbb = 2;
            sbv = (sbyte)(sba + sbb);

            byte ba, bb, bv;
            ba = 1;
            bb = 2;
            bv = (byte)(ba + bb);

            short sa, sb, sv;
            sa = 1;
            sb = 2;
            sv = (short)(sa + sb);

            ushort usa, usb, usv;
            usa = 1;
            usb = 2;
            usv = (ushort)(usa + usb);

            MessageBox.Show(string.Format("{0},{1},{2},{3}", sbv, bv, sv, usv));

这是什么原因呢?
其实CLR底层只支持 int,int64,native int, float , double几种数据类型.
像上面的sbyte,byte,short,ushort, clr底层是不支持的,在底层这些类型是用int表示的.
CLR的堆栈中压入的数字,最小是4字节,小于4字节的会根据其类型进行符号扩展或者0扩展为4字节int型.
这样四则运算的结果也是int型,最后再赋值需要进行强制类型转换.

分析一下编译后的IL代码就清楚了.

下面这个代码为什么能编译呢?
short sb;
sb=2;
sb += 1;
其实编译后的IL代码中最后赋值也包含了类型转换操作.
应该是编译器自动识别,然后自动添加的类型转换操作.

但是像上面的代码也编译出错,这个也能进行类型推断,自动添加数据类型转换啊.
不知道微软这么设计是bug还是基于其它因素的考虑?

posted on 2007-11-29 11:38  紫雨轩 .Net  阅读(3251)  评论(55编辑  收藏  举报