编译器看到的代码也许和你以为的很不一样,看看下面这个例子:
#include <iostream>
class Test
{
public:
void say() { std::cout << "say() called" << std::endl; }
};
int main()
{
((Test *)nullptr)->say();
return 0;
}
会触发空指针访问错误吗?
不会,代码可以编译运行并输出 "say() called"
因为编译器解析 ((Test *)nullptr)->say() 这行时,它实际看到的是:
Test::say(nullptr);
Test::say 是成员函数,它的地址在编译期就确定了,可以调用.而 say() 函数内部并没有访问 nullptr 空指针,所以是安全的.
再来看下面这个例子:
#include <iostream>
int main()
{
int a[3]{};
2[a] = 1;
std::cout << "a[2] = " << a[2] << std::endl;
return 0;
}
也可以正确编译运行,意外吗? 因为对编译器来说 " a[2] " 等于 " *(a + 2) ",而 " 2[a] " 等于 " *(2 + a) ", 2 出现在加号左边还是右边当然无关紧要.
关注我,一起学习 C++/Python