在阅读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) 

推荐答案

在这个版本的GCC中,这似乎是一个错误,在这个版本中,静态数组参数的大小乘以元素类型的大小,然后报告为静态大小.

看起来这是在GCC 11.0中引入的,在GCC 12.3中固定了.

https://godbolt.org/z/6sx3jPo1a

C++相关问答推荐

命名信号量不会像进程之间同步中假设的那样工作

传递给空闲的无效地址0x71 db7 cb5e0:未分配值

为什么在C中设置文件的位置并写入文件,填充空字符?

丑陋的三重间接:可扩展的缓冲区管理 struct

将 typewriter LF打印到Windows终端,而不是隐含的CR+LF

为什么双重打印与C中的float具有不同的大小时具有相同的值?

为什么在此程序中必须使用Volatile关键字?

识别和处理c中整数溢出的最佳方法?

如何在C语言中正确打印图形

Vcpkg的配置文件

如何用C语言为CLI应用程序编写按键检测系统?

如何使用FSeek和文件流指针在C中查找文件的前一个元素和前一个减go 一个元素

Fprintf正在写入多个 struct 成员,并且数据过剩

为什么WcrTomb只支持ASCII?

为什么我在C代码中得到一个不完整的类型?

在C中使用无符号整数模拟有符号整数

浮动目标文件,数据段

为什么GCC 13没有显示正确的二进制表示法?

在C中交换字符串和数组的通用交换函数

当循环变量在溢出时未定义时,可以进行哪些优化?