Tys*_*obs 1 c++ methods null pointers
该计划是否:
#include <stdio.h>
struct foo
{
void blah() {printf("blah\n");}
int i;
};
void main(int, char**)
{
((foo*)NULL)->blah();
}
Run Code Online (Sandbox Code Playgroud)
blah在你知道的任何编译器上崩溃,或者做输出以外的任何事情?当通过NULL指针调用时,任何函数是否会崩溃,如果它不访问任何成员(包括vtable)?
关于这个主题还有其他问题,例如在NULL指针上访问类成员,并且它是合法/定义良好的C++来调用不通过空指针访问成员的非静态方法吗?,并且总是指出这会导致未定义的行为.但这在现实世界中是不确定的,还是只在标准的世界中?现有的编译器是否表现不如预期?你能想到为什么未来的编译器不会按预期运行的任何合理的理由吗?
如果函数确实修改了成员,但是保护了NULL ptr.例如,
void foo::blah()
{
foo* pThis = this ? this : new foo();
pThis->i++;
}
Run Code Online (Sandbox Code Playgroud)
编辑:对于记录,我想要的原因是使我的链表类的接口尽可能简单明了.我想将列表初始化为NULL,其惯用用法如下:
pList = pList->Insert(elt);
pList = pList->Remove(elt);
...
Run Code Online (Sandbox Code Playgroud)
所有操作员返回新头元素的位置.不知怎的,我没有意识到使用容器类会让事情变得更容易,没有任何缺点.
你能想到为什么未来的编译器不会按预期运行的任何合理的理由吗?
一个有用的编译器可能会添加代码来访问调试版本中的真实对象,以期帮助您在开发周期的早期代码中捕获此问题.
如果函数确实修改了成员,但是保护了NULL ptr.例如,
void foo::blah()
{
foo* pThis = this ? this : new foo();
pThis->i++;
}
Run Code Online (Sandbox Code Playgroud)
由于使用空指针调用该函数是未定义的行为,因此编译器可以假定测试将始终通过并优化该函数:
void foo::blah()
{
this->i++;
}
Run Code Online (Sandbox Code Playgroud)
请注意,这是正确的,因为如果this不为空,它表现为,如果原来的代码被执行,如果this是零,这将是未定义行为,编译器不需要提供任何特定的行为的.
未定义的行为意味着您不能依赖将要发生的事情.但是,在调试时知道幕后发生的事情有时很有用,这样当不可能发生时你并不会感到惊讶.
大多数编译器会将其编码为带有隐藏this参数的简单函数,如果this从未引用参数,则代码将按预期工作.
检查this == NULL可能不起作用,具体取决于编译器优化的积极程度.由于一个格式良好的程序不可能具有this==NULL,编译器可以自由地假装它永远不会发生并if完全优化掉该语句.我知道微软的C++不会进行优化,因为它们的GetSafeHWND功能依赖于它按预期工作.