c - 为什么 gcc 和 clang 不警告写入地址 0?

标签 c pointers gcc clang compiler-warnings

以下错误代码:

#include <stdio.h>
#include <string.h>

void isEven (int *isFlag, int num) {
    if (num % 2 == 0) {
        *isFlag = 1;
    } else {
        *isFlag = 0;
    }
}

int main() {
    int num = 4;
    int *isFlag = 0;
    isEven(isFlag, num);
    printf("%d", isFlag);
}  
最近在一个问题中发布在 SO 上。问题本身并不重要,重要的是(对我而言)是 gcc 和 clang 警告使用 isFlag作为 printf() 的参数, neither of them警告有关如何写入地址 0 或空指针的警告。这,即使 -O3指定,确保 isEven()函数是内联的,当我还指定 -Wall -Wextra 时.
在这种情况下应该没有警告吗?

最佳答案

取消引用空指针是未定义的行为。不需要为未定义的行为发出诊断(错误或警告)。因此,从标准的角度来看,不为您的示例生成任何警告是完全可以的。
毫无疑问,让编译器检测到它会很有用,可能无法在所有情况下都检测到。
gcc 确实有 -Wnull-dereference它确实为您的示例检测并产生:

$ gcc -O3 -Wall -Wextra -Wnull-dereference -fsanitize=address test.c
test.c: In function ‘main’:
test.c:14:14: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
   14 |     printf("%d", isFlag);
      |             ~^   ~~~~~~
      |              |   |
      |              int int *
      |             %ls
test.c:4:17: warning: null pointer dereference [-Wnull-dereference]
    4 |         *isFlag = 1;
      |         ~~~~~~~~^~~
来自 gcc documentation :

-Wnull-dereference
Warn if the compiler detects paths that trigger erroneous or undefined behavior due to dereferencing a null pointer. This option is only active when -fdelete-null-pointer-checks is active, which is enabled by optimizations in most targets. The precision of the warnings depends on the optimization options used.

关于c - 为什么 gcc 和 clang 不警告写入地址 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66822909/

相关文章:

c - 检查矩阵特殊模式的算法

c++ - 为什么我必须在 "original"指针上调用 delete?

c - 为什么 gcc 有时会为本地分配额外的空间而有时却不会?

c - 如何在 C 中获取与寄存器宽度无关的无符号整数变量?

c - 为什么数组的值后面跟着三个零?

c - GCC是否缓存循环变量?

c++ - 如何使用 QTextStream 而不是 QDataStream 从 QTableView 进行加载保存?

c - 使用 C 进行客户端服务器编程速度慢

javascript - 以一种好的方式从链表中删除项目

c - 用指针在c中打乱链表