在我看来,以下程序计算了一个无效的指针,因为NULL除了赋值和比较相等以外,没有其他好处:

#include <stdlib.h>
#include <stdio.h>

int main() {

  char *c = NULL;
  c--;

  printf("c: %p\n", c);

  return 0;
}

但是,似乎GCC或Clang中针对未定义行为的警告或手段都没有说这实际上是UB。该算术实际上有效吗?我太学究了,或者这是我应该报告的检查机制的缺陷吗?

经测试:
$ clang-3.3 -Weverything -g -O0 -fsanitize=undefined -fsanitize=null -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull
c: 0xffffffffffffffff

$ gcc-4.8 -g -O0 -fsanitize=address offsetnull.c -o offsetnull
$ ./offsetnull
c: 0xffffffffffffffff

似乎有充分的文献记载,Clang和GCC使用的AddressSanitizer更着重于坏指针的取消引用,因此这很公平。但是其他检查也没有捕获它:-/

编辑:我问这个问题的部分原因是-fsanitize标志启用了对生成代码中定义明确的动态检查。这是他们应该捕获的东西吗?

最佳答案

未指向数组的指针的指针算术是未定义的行为。
同样,取消引用NULL指针也是未定义的行为。

char *c = NULL;
c--;

是未定义的行为,因为c不指向数组。

C++ 11标准5.7.5:

08-19 18:12