编译器对基元类型的特殊对待

无论是从语法方面,还是从代码优化方面,编译器都会对基元类型进行特殊的对待。这些特殊对待主要体现在运算,直接量,操作符重载。下面一一讨论。

    一,基元类型的运算

   在基元类型的运算方面,C#编译器所提供的最大的特性就是,能够根据用户的设置进行溢出检查,当产生溢出时CLR抛出一个异常,这样用户就可以检查并处理这个异常。在默认情况下,编译器是不会进行溢出检查的,如下:

        private static void AddTwoInteger()
        {
                int a = int.MaxValue;
                int b = 12;
                long c = a + b;
           
        }

根据直觉,这段代码中,c会等于2147483659(2147483647+12);但事实c却等于-2147483648。

a+b运算产生了溢出,但是在运行的时候却没有抛出异常,这不是我想要的。那么如何让这段代码在运行的时候抛出一个异常呢,这可以通过使用checked来检查溢出,当checked内的运算发生了溢出,checked就会抛出一个异常。将代码修改如下:

        private static void AddTwoInteger()
        {
           checked
            {
                int a = int.MaxValue;
                int b = 12;
                long c = a + b;
            }
        }

从新编译这段代码,就会在运行的时候抛出一个overflowException异常。然后可以捕获这个异常,采取处理。


那么为什么加上一个checked之后 ,就会在运算产生溢出时抛出一个异常呢?通过查看IL代码可以找到答案。

在用checked修饰的那段代码中,编译器为a+b运算生成了一个add.ovf指令,而这个指令最大的特点就是在执行加法运算的时候,如果结果太大,也就是产生了溢出时会抛出一个OverflowException异常。

而第一段代码中,由于没有使用check,所以编译器就生成一个add指令,这个指令在结果产生溢出的时候不会抛出一个异常。


都有哪些运算可能产生溢出?

1.加法运算可能会产生溢出

2.加法运算可能会产生溢出

2.乘法运算可能会产生溢出

3.将一个宽数据转为窄数据时可能会产生溢出(譬如将Int64转为Int32)


如何在实际开发中使用溢出检查?

     由于溢出检查会带来性能损失,因为在溢出的时候会抛出异常。因此在release版中是不太会使用溢出检查的,一般都是在Debug版中进行溢出检查,原因很简单,就是便于调试,试想一想如果不使用溢出检查,当代码中出现溢出运算时,程序依旧会悄然无声的运行,就像什么都没有发生一样,对于这样的操作找出错误的发生很是困难。

    为了使用溢出检查,会在代码中大量的嵌入checked,然后还要在发布版本去掉他们。还有一些更简单的方法,那就是使用csc命令行工具编译源代码时使用checked参数,如下:

在debug中使用上述的checked+命令行编译,就会在生成的IL指令中使用类似于add.ovf这样带溢出检查的指令。我们完全不用在源代码中使用checked关键咯。当要生成release版时,则使用checked-,就不会使用溢出检查了。

事实上,正如开始所说的,编译器默认是不进行溢出检查的。所以上述命令行完全可以去掉checked-参数。

二,直接量

   由于编译器对直接量的支持,所以下面代码能够正常编译:

string a = 1.ToString();

  可以看出,对于直接量的支持,完全是为了简便用户的一些输入而已。譬如如果编译器不支持直接量,那么要想将整形2转换为string,则必须要这样写:

Int32 x=2;
string a = x.ToString();
三,操作符的支持

   同样,编译器提供操作符也只是为了简化用户输入而已,并使代码更符合我们的直觉,如下:

 

int a=2;
int b=3;
int c=a+b

使用+来进行加法运算时再自然不过的了,所以提供操作重载是很有好处的。但这并不是必要的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值