这是代码风格和传统的问题,我想,但问题如下。
假设我们有一个检查参数的函数,例如:
int do_something(int * arr) {
if (arr == NULL) {
printf("arr is NULL\n");
return -1;
}
...
现在我们将使用它。 问题是:我们应该检查一下我们要传递给它的论点吗?无论如何它会检查它。
这个例子相当简单,现实生活场景可能要困难得多,有更多的参数(和更复杂的检查)以及调用函数带来的更多额外开销 - 如果这是某种IPC。
更一般的问题是:关于这种情况的常见指导方针和做法是什么?
答案 0 :(得分:2)
这将基于个人经验和偏见。无论如何,这就是:
如果do_something
属于某个库,并且作为可以直接调用的函数向库的用户公开,则最好进行必要的所有检查以确保{{1}很健壮。
如果它是库中的内部函数,最好还是进行必要的检查以确保do_something
是健壮的。我做出的唯一例外是,如果程序/库的性能受到支票的不利影响,我会做出检查。
如果它是您自己的应用程序中的一个函数,最好还是必须进行所有必要的检查,以确保do_something
是健壮的。我做出的唯一例外是,如果程序/库的性能受到支票的不利影响,我会做出检查。
答案 1 :(得分:0)
如果将该功能记录为检查参数,则在没有检查的情况下调用它。例如,free()
被明确记录为接受NULL
作为参数,因此编写过于常见的内容没有意义
if(p != NULL)
free(p);
它使您的代码混乱,没有任何好处。避免不必要的呼叫的好处通常在噪声中完全消除。
当然,您必须检查函数的返回值。
如果您是函数的实现者,无论是库函数还是本地帮助函数,甚至可以在某些编译器上注释函数的特定契约。
例如,如果您的函数不接受NULL
指针,则可以在函数声明中设置(在gcc上)__attribute__((nonnull))
。
如果您声明例如:
int do_something(int * arr) __attribute__((nonnull (1)));
你会知道你不能用NULL
来调用函数(编译器甚至会在它知道你的情况下发出警告)。但要小心,这个属性可能会让人感到惊讶。如果你像我一样声明它并且你仍然会像在示例中那样检查参数,那么你会发现优化器完全从对象代码中删除了检查。