当我在c / cpp中执行int * p = p时会发生什么?

时间:2015-04-06 12:04:41

标签: c++ pointers

下面的代码是在MinGw中编译的。它是如何编译的?如何分配尚未创建的变量?

 int main()
{
    int*p=p;
    return 0;
}

3 个答案:

答案 0 :(得分:5)

  

如何编译?

变量的声明点从其声明符的末尾开始,但在其初始化之前。这允许更合理的自引用声明,如

void * p = &p;

以及像你这样的未定义的初始化。

  

如何分配尚未创建的变量?

这里没有任何作业,只是初始化。

已创建变量(在为其分配存储空间的意义上),但未初始化。您可以从该存储中发生的任何不确定值初始化它,具有未定义的行为。

如果您要求,大多数编译器会发出有关使用未初始化值的警告或错误。

答案 1 :(得分:1)

让我们来看看int*p=p;语句会发生什么:

  1. 编译器在堆栈上分配空间以保存变量p
  2. 的未初始化值
  3. 然后编译器使用未初始化的值
  4. 初始化p

    因此,基本上代码应该没有问题,除了它为变量赋予一个未初始化的值。

    实际上与以下代码没有太大区别:

    int *q;        // define a pointer and do not initialize it
    int *p = q;    // assign the value of the uninitizlized pointer to another pointer
    

答案 2 :(得分:0)

可能的结果("它编译成")将是一个未完全初始化的指针变量的声明(由于它不是使用,所以最终的结果将是"空主#34;)。

声明并初始化指针。到目前为止,这是一件普通而合法的事情。但是,它被初始化为自身,并且它的值仅在语句结束后(即分号的位置)处于有效的初始化状态之后。
不出所料,这使得语句未定义行为。

根据定义,调用未定义的行为原则上可能导致几乎所有事情(虽然经常引用戏剧效果,例如格式化硬盘或将计算机置于火上都会被夸大)。

编译器实际上可能会生成一个指令,将寄存器(或内存位置)移动到自身,这在大多数体系结构上都是无操作指令,但可能会导致硬件异常,从而在一些特殊的体系结构中杀死您的进程验证指针寄存器(如果"随机"值绝对是无效地址)。
但是编译器不会插入任何"格式的硬盘"语句。

在实践中,优化编译器现在经常假设&#34;当它们遇到未定义的行为时没有发生<#em> ,所以很可能编译器只会尊重声明,什么都不做。
从各方面来说,这是完全允许的,因为未定义的行为。此外,它是编译器最简单,最麻烦的选择。