意外的输出而不是运行时错误

时间:2015-03-19 07:19:14

标签: c++

对于谁知道背景魔法可能是显而易见的,但我无法理解下面的代码如何提供正确的输出。我预计运行时错误。请帮忙。

class a
{
  public:
    void print()
    {
        cout<<"Hello\n"<<endl;
        int d = 100;
        cout<<d<<endl;
    }

    int val;
};


int main()
{
   a* ptr;

   ptr->print();

   return SUCCESS;
}

OUTPUT如下:

Hello

100

2 个答案:

答案 0 :(得分:5)

没有魔力 - 您的代码有未定义的行为。在您的代码中,您不能访问ptr作为print()指针隐式传递给this,这就是没有错误发生的原因。

在其他几种情况下可能会发生:

  • 访问a个实例的字段。它将需要读取将导致运行时错误的内存*(this + field_offset)

  • 访问虚拟方法。我已知的实现使用 vtable 来执行此操作,通常将其存储为对象空间中的第一个指针,因此指向 vtable 的指针将与此相同,因此:{{1 }}

  • 其他情况,取决于编译器和平台

注意:vtable = *this

的示例中省略了类型转换

答案 1 :(得分:4)

a::print不是虚方法,因此它只是一个普通函数,它有一个额外的参数来接收this指针。由于该方法从不使用this指针,因此它未初始化的事实不会变成内存访问错误或其他故障。在这种情况下,声明a::print static仍然会编译,因为它没有使用this指针。在方法中声明a::print virtual或访问this可能会导致程序崩溃,至少在某些情况下会如此。

行为仍然未定义,并且它是一个格式错误的程序,但是现在它很可能在大多数系统上确定性地工作。通常,C ++不会为这种情况提供运行时错误,但是如果您使用例如&#34; clang ++ -Wall&#34;将给出一个警告,表明未初始化的变量。 (还有像clang的asan这样的工具可以进一步诊断这些错误。)