我在几个旧项目中看到过这样的代码:
class Class {
static void Method() {}
};
((Class*)0)->Method();
此代码包含未定义的行为,因为它包括取消引用空指针(无论之后发生什么)。它真的没有任何意义 - 演员是在那里将类型名称提供给编译器,而编写上述代码的人可能会写这个:
Class::Method();
后者可以。
为什么有人会编写前代码?它是一个已知的成语来自一些美好的旧时代或什么?
答案 0 :(得分:67)
静态成员函数于1989年在AT& T C ++语言系统(预标准化)的Release 2.0中添加到C ++中。在此之前,static
关键字不能用于声明静态成员函数,因此代码作者使用了变通方法,主要是您观察到的间接空指针的方法。
在AT& T C ++语言系统的Selected Readings附带版本2.0中,在第1-22节中,Stroustrup写道:
还观察到了不可移植的代码,例如:
((X*)0)->f();
用于模拟静态成员函数。这个技巧是一个定时炸弹,因为迟早有人会以这种方式
f()
使用virtual
并且调用将会失败,因为地址为零时没有X
个对象。即使f()
不是虚拟的,在某些动态链接实现下,这样的调用也会失败。
您的代码是在Cfront 1.0下编译的,或者是在向该语言添加静态成员函数时不知道的人编写的。
使用static
的成员函数的注释确实是一个难题,如干杯和hth。 - Alf 观察到了; Cfront 1.0会拒绝该代码:
error: member Method() cannot be static
所以它最初不可能存在。我认为 Potatoswatter 最有可能是正确的;稍后添加static
来记录并强制执行Method
的静态方法属性,一旦C ++ 2.0编译器可以保证可用,但不更新调用代码。要确认这一点,您需要采访原始程序员或至少检查源控制历史记录(如果存在)。