nullptr和指针算术

问题描述:

考虑到下面的代码,在nullptr上做指针运算是否安全?nullptr和指针算术

我想添加任何偏移量为nullptr导致另一个nullptr,到目前为止MSVC产生的结果如我所料,不过我有点不确定使用nullptr这样是否安全:

float * x = nullptr; 

float * y = x + 31; // I assume y is a nullptr after this assigment 

if (y != nullptr) 
{ 
    /* do something */ 
} 

你没不要定义“安全”对您意味着什么,但不管您提出的代码具有未定义的行为。指针算术只允许指向数组对象的指针值,或者指向数组的一个末尾。 (对于此规则,非数组对象被认为是一个元素的数组)。

由于空指针永远不是对象的地址或通过对象的地址,因此您的代码永远不会有定义良好的行为。

+0

'int * a; a ++;'是UB,即使我不取消引用指针?你能给一个参考吗? – user463035818

+4

@ tobi303:没有参考,因为标准没有明确说明它是未定义的。 [expr.add]/5定义了指针+ integer * only *对指向数组的指针(或指向对象,其作为1的数组)的行为。如果指针未指向数组,则根据定义,行为是未定义的(除了在加0的情况下,对所有指针定义的[expr.add]/8)。 –

+3

@ tobi303 UB并不意味着“崩溃”,它的意思是“我们没有定义这是什么”。碰巧,编译器可以积极地优化和检测UB,并导致程序出乎意料地行为。一所优化学校“因为UB不能在良好的程序中出现,所以导致UB的任何逻辑链都可以安全地消除,直到并且包括在代码中跳过明确的”if“检查。简而言之,UB会导致*时间旅行*错误,远离UB的代码的行为方式与您编写的代码不匹配。 – Yakk

不,将偏移量添加到nullptr不会导致nullptr。这是未定义的行为。

+2

添加非零偏移量不会导致nullptr是正确的。然而,向空指针加零/从零指针中减去零是明确定义的,并产生一个空指针(这是C和C++之间的一个特定区别 - 在C中这是未定义的)。 – Peter

...在nullptr上做指针运算是否安全?

不,算术nullptr没有很好的定义,因为它本身不是一个指针类型(但转换为所有指针类型的NULL值存在)。

See here;

std::nullptr_t是空指针文字的类型,nullptr。它是一种独特的类型,它本身不是指针类型或指向成员类型的指针。


一般情况下,任意的指针运算(甚至NULL值)几乎肯定会导致问题 - 你没有分配内存 - 这是不是你尝试读取或写入。

出于比较目的(例如,结束时),您将会很好,但否则您的代码将导致未定义的行为。

欲了解更多信息,请参阅*undefined behavior

+0

我不确定第二段中的逻辑:指针算术不会导致从内存读取或写入内存。记忆与OP的问题无关。 –

+0

这更多的是关于OP的任意部分问题。我会把它清理干净。 – Niall

is it safe to do pointer arithmetic on nullptr? 

C++ 限定两种上nullptr操作。适用于:

float * x=nullptr; 
float * y=nullptr; 
  1. x +/- 0 = x

  2. x-y=0 //note x and y have the same type

你不能对什么是没有定义的假设,所以你不应该这样做。

+1

实际上,还有第三个操作定义为:'x == y'。看起来微不足道,但它确实意味着只有一个空指针值。 – MSalters