在阅读Modern C时,我试图判断如果我传递指向以下任一函数的空指针,GCC是否会发出诊断消息:
#include <stdio.h>
#include <stdlib.h>
#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER)
#define ATTRIB_NONNULL(...) __attribute__((nonnull(__VA_ARGS__)))
#else
#define ATTRIB_NONNULL(...) /* If only. */
#endif
size_t my_strlen(const char *s[static 1])
{
size_t count = 0;
while (*s++) {
++count;
}
return count;
}
ATTRIB_NONNULL(1) size_t my_strlen1(const char *s)
{
size_t count = 0;
while (*s++) {
++count;
}
return count;
}
int main(void)
{
return my_strlen(NULL), my_strlen1(NULL);
}
它产生的输出是这样的(make null_diagnostic
):
null_diagnostic.c: In function ‘main’:
null_diagnostic.c:34:29: warning: argument 1 null where non-null expected [-Wnonnull]
34 | return my_strlen(NULL), my_strlen1(NULL);
| ^~~~~~~~~~
null_diagnostic.c:21:26: note: in a call to function ‘my_strlen1’ declared ‘nonnull’
21 | ATTRIB_NONNULL(1) size_t my_strlen1(const char *s)
| ^~~~~~~~~~
null_diagnostic.c:34:12: warning: argument 1 to ‘const char *[static 8]’ is null where non-null expected [-Wnonnull]
34 | return my_strlen(NULL), my_strlen1(NULL);
| ^~~~~~~~~~~~~~~
null_diagnostic.c:10:8: note: in a call to function ‘my_strlen’
10 | size_t my_strlen(const char *s[static 1])
| ^~~~~~~~~
它确实像预期的那样引发了诊断信息,但它提到了将空指针传递给预期为const char *[static 8]
而不是const char *[static 1]
的函数.为什么它希望参数至少有8个长度?我遗漏了什么?
以下是编译器信息:
gcc version 11.4.0 (Ubuntu 11.4.0-1ubuntu1~22.04)