zoukankan      html  css  js  c++  java
  • <VCC笔记> 溢出与unchecked

    在程序运算或者数据转换的时候,由于各种数据类型有各自的范围,运算的时候,其结果如果超出这个范围,就被称之为溢出。熟悉C#的同志们应该了解用来解决溢出(Overflow)问题的checked,unchecked这两个关键字。而VCC也有类似的设定。

    溢出是有规律的,有时候代码原本的设计就是要利用溢出这一特性。但是VCC(以及C#)不愿意默认程序在利用溢出,所以发生溢出的时候会报错。因此有unchecked。

    #include <vcc.h> 
    
    unsigned hash(unsigned char∗s, unsigned len) 
    _(requires 	hread_local_array(s, len)) 
    { 
        unsigned i, res; 
        for (res = 0, i = 0; i < len; ++i) 
        res = (res + s[i])∗13; 
        return res; 
    }

    结果会是:

    Verification of hash failed.

    testcase(9,11) : error VC8004: (res + s[i]) ∗ 13 might overflow.

    VCC敏锐地察觉到(res + s[i]) ∗ 13这里的运算可能溢出。但是这个代码是想要利用溢出的,这时候需要使用_(unchecked)。

    改成” res = _(unchecked)((res + s[i])∗13); “,上面的代码就不会报错了。

    例子:

    int a, b; 
    
    // ... 
    
    a = b + 1;
    
    _(assert a < b)

    这样子,VCC要么报overflow,要么验证成功,这取决于之前的代码产生的推断。

    int a, b; 
    
    // ... 
    
    a =  _(unchecked)(b + 1);
    
    _(assert a < b)

    像这样子,他不会报错说overflow。如果他不能推断出b+1不会溢出,他会报错assertion不能保证。

    以下是VCC的对于_(unchecked)E的理解:

    • if the value of E lies within the range of its type, then E == _(unchecked)E;

    • if x and y are unsigned, then _(unchecked)(x+y)== (x+y <= UINT_MAX ? x+y : x + y−UINT_MAX), and similarly for other types;

    • if x and y are unsigned, then_(unchecked)(x−y)== (x >= y ? x− y : UINT_MAX−y + x + 1), and similarly for other types.

    以上。

  • 相关阅读:
    牛客前缀和题、枚举---[HNOI2003]激光炸弹
    牛客贪心题---拼数
    牛客枚举题---明明的随机数
    牛客模拟、差分题---校门外的树
    牛客贪心题---纪念品分组
    03_7_继承和权限控制
    03_6_package和import语句
    03_5_static关键字
    01_8_sql主键生成方式
    01_7_模糊查询实体对象
  • 原文地址:https://www.cnblogs.com/aureate-sunshine/p/5021319.html
Copyright © 2011-2022 走看看