我最近才知道assert
在 C 中可以用于调试。
我编写了下面的 C 代码片段以确保输入不为零。
示例代码——
#include <stdio.h>
#include <assert.h>
int main(){
int a;
scanf("%d",&a);
assert(a != 0);
return 0;
}
我想问一下我们是否也可以assert
在 C 中使用来检查变量赋值溢出?
例如:
long a = X;
int b = a + 40;
assert((long)b == a + 40);
为了避免未定义的行为,您希望assert
离子在整数溢出之前发生。
Perreal 的代码是朝着正确方向迈出的一步,但它并不完美,因为它通过在断言之前溢出整数来调用未定义的行为。
这是我要使用的示例:
long a = X;
assert(a < LONG_MAX - 40); /* Assert that a is less than LONG_MAX - 40, which
* proves that we can add 40 without invoking
* undefined behaviour.
*/
assert(a + 40 >= INT_MIN);
assert(a + 40 <= INT_MAX); /* Assert that once 40 is added, the result will fit
* into an int without invoking implementation defined
* behaviour.
*/
int b = a + 40;
assert()
用于输入验证不是一个好主意。有两个原因:
-DNDEBUG
或等效编译的。您应该通过其他机制处理输入错误。例如:
#include <stdio.h>
int main(void)
{
int a;
if (scanf("%d", &a) != 1)
...report I/O problem...
else if (a == 0)
...report invalid input...
else
...use known-to-be-non-zero value...
return 0;
}
请注意,scanf()
函数族不能优雅地处理整数溢出。如果您对此感到担忧,请考虑使用函数读取数据fgets()
,然后使用strtol()
或其亲属之一来转换字符串;这些函数确实处理和报告溢出。
使用(有符号的)整数溢出计算,您可以使用它assert()
来确保值不会溢出(在溢出发生后断言为时已晚;您调用了未定义的行为并且任何事情都可能发生)。但是,您应该考虑 的错误报告行为assert()
是否可以接受。