<VCC笔记> 溢出与unchecked

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

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

#include <vcc.h> 

unsigned hash(unsigned char∗s, unsigned len) 
_(requires \thread_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.

以上。

posted @ 2015-12-05 15:20  阳光是金色的  阅读(336)  评论(0编辑  收藏  举报

Always loyal to lorreta!