在不访问任何数据的NULL指针上调用方法是否会失败? [英] Does calling a method on a NULL pointer which doesn't access any data ever fail?

查看:78
本文介绍了在不访问任何数据的NULL指针上调用方法是否会失败?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

程序将会

#include <stdio.h>

struct foo
{
   void blah()  {printf("blah\n");}
   int i;
};

void main(int, char**)
{
   ((foo*)NULL)->blah();
}

在您知道的任何编译器上是否发生崩溃,或执行除输出blah以外的任何操作?如果通过NULL指针调用的任何函数不访问任何成员(包括vtable),是否会使其崩溃?

Ever crash, or do anything other than output blah, on any compiler you are aware of? Will any function crash, when called via a NULL pointer, if it doesn't access any members (including the vtable)?

关于此主题还有其他问题,例如在空指针

There have been other questions on this topic, for instance Accessing class members on a NULL pointer and Is it legal/well-defined C++ to call a non-static method that doesn't access members through a null pointer?, and it is always pointed out that this results in undefined behavior. But is this undefined in the real world, or only in the standard's world? Does any extant compiler not behave as expected? Can you think of any plausible reason why any future compiler wouldn't behave as expected?

如果函数修改成员,但防止使用NULL ptr,该怎么办?例如,

What if the function does modify members, but the NULL ptr is guarded against. For instance,

void foo::blah()
{
   foo* pThis = this ? this : new foo();
   pThis->i++;
}

修改: 出于记录的原因,我想要这样做的原因是使链接列表类的接口尽可能简单明了.我想将列表初始化为NULL,具有惯用用法:

Edit: For the record, the reason I wanted this was to make the interface to my linked list class as easy and concise as possible. I wanted to initialize the list to NULL have idiomatic usage look like:

pList = pList->Insert(elt);
pList = pList->Remove(elt);
...

所有运算符都将在其中返回新的head元素.不知何故,我没有意识到使用容器类会使事情变得更加简单,而且没有任何缺点.

Where all the operators return the new head element. Somehow I didn't realize that using a container class would make things even easier, with no downside.

推荐答案

您能想到任何可能的原因,为什么将来的任何编译器都无法达到预期的效果吗?

Can you think of any plausible reason why any future compiler wouldn't behave as expected?

有用的编译器可能会在调试版本中添加代码以访问实际对象,以期帮助您在开发周期的早期就在代码中捕获此问题.

A helpful compiler might add code to access the real object under the hood in debug builds in the hope of helping you catch this issue in your code early in the development cycle.

如果该函数确实修改了成员,但谨防NULL ptr,该怎么办.例如,

What if the function does modify members, but the NULL ptr is guarded against. For instance,

void foo::blah()
{
   foo* pThis = this ? this : new foo();
   pThis->i++;
}

由于使用空指针调用该函数是不确定的行为,因此编译器可以假定测试将始终通过并将该函数优化为:

Since it is undefined behavior to call that function with a null pointer, the compiler can assume that the test will always pass and optimize that function to:

void foo::blah()
{
   this->i++;
}

请注意,这是正确的,因为如果this不为null,则它的行为与执行原始代码的情况相同,如果this为null,则它是未定义的行为,并且编译器根本不需要提供任何特定的行为.

Note that this is correct, since if this is not null, it behaves as-if the original code was executed, and if this was null, it would be undefined behavior and the compiler does not need to provide any particular behavior at all.

这篇关于在不访问任何数据的NULL指针上调用方法是否会失败?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆