c++ - 是否对空指针未定义的行为执行算术?

标签 c++ c language-lawyer undefined-behavior null-pointer

在我看来,下面的程序计算了一个无效的指针,因为 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 标志启用 dynamic 检查生成的代码。这是他们应该捕获的东西吗?

最佳答案

不指向数组的指针的指针运算是未定义的行为。
此外,取消引用 NULL 指针是未定义的行为。

char *c = NULL;
c--;

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

C++11 标准 5.7.5:

When an expression that has integral type is added to or subtracted from a pointer, the result has the type of the pointer operand. If the pointer operand points to an element of an array object, and the array is large enough, the result points to an element offset from the original element such that the difference of the subscripts of the resulting and original array elements equals the integral expression. In other words, if the expression P points to the i-th element of an array object, the expressions (P)+N (equivalently, N+(P)) and (P)-N (where N has the value n) point to, respectively, the i + n-th and i − n-th elements of the array object, provided they exist. Moreover, if the expression P points to the last element of an array object, the expression (P)+1 points one past the last element of the array object, and if the expression Q points one past the last element of an array object, the expression (Q)-1 points to the last element of the array object. If both the pointer operand and the result point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

关于c++ - 是否对空指针未定义的行为执行算术?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15608366/

相关文章:

c++ - Pageheap 不会让我的应用程序中断

c++ - 对象什么时候获取内存?

c++ - 检查进程 ID 时使用 WaitForSingleObject 的好处

c - 在基于 C 的语言中,从右到左和从左到右的关联性有什么后果?

c - 有理数转换为long int

c++ - 带 auto 的 initializer_list 包含多个表达式

c++ - 数组 vector 的内存布局是什么?

c++ - 尝试运行已编译的 C++ 代码时出现段错误 11

c - C头文件如何导入win32api函数?

c++ - 声明时可以使用变量吗?