Jos*_*vin 7 c++ methods null standards pointers
我最近遇到了以下代码:
class Foo
{
public:
void bar();
// .. other stuff
};
void Foo::bar()
{
if(!this) {
// .. do some stuff without accessing any data members
return;
}
// .. do normal actions using data members
}
Run Code Online (Sandbox Code Playgroud)
代码编译是因为在C++方法中只是隐式传递'this'指针的函数,'this'可以像任何其他指针一样被检查为NULL.显然,即使它没有崩溃,这段代码也会让人感到困惑和不好.在调试器中单步调试代码会非常混乱,看到一个NULL指针即将有一个调用它的方法,然后看不到预期的崩溃.我的问题是:它是否违反了C++标准来调用SomeFooPtr->bar()哪里SomeFooPtr == NULL?
我发现它可能不是因为用户定义的operator->返回一个指针,这意味着即使该指针为NULL,它肯定没有被解除引用(取消引用一个NULL指针我敢肯定被标准视为非法或未定义).另一方面,原始指针的语义不一定必须与用户定义的指针的语义匹配 - 也许操作符 - 对它们来说被认为是解除引用,即使编译器不会生成一个.
Tho*_*mas 13
这可能适用于大多数系统,但它是未定义的行为.标准:
5.2.5.3
如果
E1类型为"指向类X的指针",则表达式E1->E2将转换为等效形式(*(E1)).E2[...]
和:
5.2.5.1
后缀表达式后跟一个点
.或箭头->,可选地后跟关键字template(14.8.1),然后是id-expression,后缀表达式.评估点或箭头之前的后缀表达式; 58) [...]58)即使结果不必确定整个后缀表达式的值,也会发生此评估,例如,如果id-expression表示静态成员.
评价*x这里x是不确定的行为一个空指针的结果,所以你显然是UB的情况下,即使进入该功能前.
即使取消引用不是UB,此测试也会被破坏.当多重继承的调整进入游戏时,它会中断:
#include <stdio.h>
class B
{
int value;
public:
void foo()
{
if (!this)
printf("this==0\n");
else
printf("safe\n");
}
};
class A { public: int anotherValue; };
class Z : public A,public B {};
int main()
{
Z *z=0;
z->foo();
}
Run Code Online (Sandbox Code Playgroud)
在这里打印"安全".