0

我最近才知道assert在 C 中可以用于调试。

我编写了下面的 C 代码片段以确保输入不为零。

示例代码——

#include <stdio.h>
#include <assert.h>
int main(){
    int a;
    scanf("%d",&a);
    assert(a != 0);
    return 0;
}

我想问一下我们是否也可以assert在 C 中使用来检查变量赋值溢出?

4

3 回答 3

2

例如:

long a = X;
int  b = a + 40;
assert((long)b == a + 40);
于 2013-07-08T04:27:27.530 回答
2

为了避免未定义的行为,您希望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;
于 2013-07-08T05:52:19.593 回答
0

assert()用于输入验证不是一个好主意。有两个原因:

  1. 如果断言没有被强制执行,您的代码可能会失败,因为它是使用-DNDEBUG或等效编译的。
  2. 最终用户通常不能接受错误处理行为;就他们而言,这次崩溃适得其反。

您应该通过其他机制处理输入错误。例如:

#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()是否可以接受。

于 2013-07-08T06:10:18.317 回答