当我调用一个需要指针的函数并传入一个值时,我得到了这个警告,我喜欢这样。
但是当该值恰好是文字“0”时,我没有收到警告。我认为这是因为 C 认为它是空指针,而不是值。有什么办法仍然会收到 0-literals 的警告,因为我已经因此而遇到了一些错误。
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);
不幸的是,没有使用原始 C 编译器。您应该尝试使用 lint 工具,如夹板,这可能会对您有所帮助(不过我不确定)。
有没有办法仍然收到 0-literals 的警告
我不知道一个,反正你不想要那个。常量数值 0 在分配给指针时被隐式处理为NULL
没有将其强制转换为指针类型。
我认为转换为 null 可能是编译器固有的 - 但是静态检查这些情况应该很容易,因为它们是相当独特的。
如果您希望传递 null 而不是 (int)0,请使用显式 NULL 枚举或定义,然后使用与模式 YourFunction(0); 匹配的任何内容;(允许空白)绝对是无效的。如果您想使用低技术,则可以很容易地使用 Grep。正如 Fabien 建议的那样,各种 lint 工具可能能够做到这一点。
在编码时,我总是尽量记住,如果可以的话,尽可能让错误的东西看起来是错误的,这样你就可以更容易地检测到它们。
这个问题与问题类似。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'
如果你必须。
此信息来自此链接