7

当我调用一个需要指针的函数并传入一个值时,我得到了这个警告,我喜欢这样。

但是当该值恰好是文字“0”时,我没有收到警告。我认为这是因为 C 认为它是空指针,而不是值。有什么办法仍然会收到 0-literals 的警告,因为我已经因此而遇到了一些错误。

4

5 回答 5

5

GCC 支持nonnull函数参数的属性,可以做你想做的事情(只要-Wnonnull启用警告选项):

void* foo( int* cannot_be_null)  __attribute((nonnull (1))) ;


int main(int argc, char *argv[])
{
    int x;
    foo(&x);

    foo(0);  // line 13 - generates a -Wnonnull warning

    return 0;
}

使用编译时,gcc -c -Wnonnull test.c我得到:

test.c: In function 'main':
test.c:13:5: warning: null argument where non-null required (argument 1) [-Wnonnull]

您可以强制这是一个错误-Werror=nonnull

请注意,仅当使用空指针文字(的另一个名称0)时才会引发此警告 - 以下代码不会触发警告:

int* p = NULL;
foo(p);
于 2013-01-30T18:22:14.417 回答
1

不幸的是,没有使用原始 C 编译器。您应该尝试使用 lint 工具,如夹板,这可能会对您有所帮助(不过我不确定)。

于 2013-01-30T18:00:01.450 回答
0

有没有办法仍然收到 0-literals 的警告

我不知道一个,反正你不想要那个。常量数值 0 在分配给指针时被隐式处理为NULL没有将其强制转换为指针类型。

于 2013-01-30T17:59:53.920 回答
0

我认为转换为 null 可能是编译器固有的 - 但是静态检查这些情况应该很容易,因为它们是相当独特的。

如果您希望传递 null 而不是 (int)0,请使用显式 NULL 枚举或定义,然后使用与模式 YourFunction(0); 匹配的任何内容;(允许空白)绝对是无效的。如果您想使用低技术,则可以很容易地使用 Grep。正如 Fabien 建议的那样,各种 lint 工具可能能够做到这一点。

在编码时,我总是尽量记住,如果可以的话,尽可能让错误的东西看起来是错误的,这样你就可以更容易地检测到它们。

于 2013-01-30T18:10:14.267 回答
0

这个问题与问题类似。Should I use symbolic names like TRUE and FALSE for Boolean constants, or plain 1 and 0?

C 程序员必须理解 NULL 和 0 在指针上下文中是可以互换的,并且未转换的 0 是完全可以接受的。NULL (相对于 0)的任何使用都应该被视为一个温和的提醒,即涉及到一个指针;程序员不应该依赖它(为了他们自己的理解或编译器的理解)来区分指针 0 和整数 0。

只有在指针上下文中 NULL 和 0 是等价的。当需要另一种 0 时,不应使用 NULL,即使它可能有效,因为这样做会发送错误的风格信息。(此外,ANSI 允许将 NULL 定义为 ((void *)0),这在非指针上下文中根本不起作用。)特别是,当需要 ASCII 空字符 (NUL) 时不要使用 NULL。提供您自己的定义

#define NUL '\0'

如果你必须。

此信息来自此链接

于 2013-01-30T18:39:01.950 回答