繁体   English   中英

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

[英]What happens when I do int*p=p in c/cpp?

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

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

如何编译?

变量的声明点始于其声明器的末尾,但始于其初始化器。 这允许使用更多合法的自我引用声明,例如

void * p = &p;

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

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

这里没有分配,只有初始化。

变量已创建(就分配了存储而言),但尚未初始化。 您可以使用存储在存储中的任何不确定值来初始化它,并且行为不确定。

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

让我们看一下int*p=p;会发生什么int*p=p; 声明:

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

因此,除了为变量分配未初始化的值之外,代码基本上应该没有问题。

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

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

可能的结果(“编译结果”)将是一个指针变量的声明,该变量根本没有初始化(由于未使用它,随后对其进行了优化,因此最终结果将是“空主”)。

指针被声明和初始化。 到目前为止,这是一件普通且合法的事情。 然而,它被初始化为本身,其价值只在语句结束有效,初始化状态(即,在分号的位置)。
毫不奇怪,这使语句具有不确定的行为。

根据定义,调用未定义的行为原则上可能会导致几乎所有事情(尽管经常会引用格式化硬盘或使计算机着火的戏剧性效果)。

编译器实际上可能会生成一条指令,将寄存器(或内存位置)移至自身,这在大多数体系结构上都是无操作指令,但可能会导致硬件异常,从而在某些具有特殊验证寄存器的奇异体系结构上杀死您的进程指针(如果“ random”值偶然是无效地址)。
但是,编译器不会插入任何“格式硬盘”语句。

在实践中,如今,优化编译器在遇到未定义的行为时通常会假设“没有发生” ,因此,编译器很可能只会遵守该声明, 而不执行其他任何操作。
每种情况下,鉴于未定义的行为,这是完全允许的。 此外,对于编译器而言,这是最简单,最麻烦的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM