的含义是什么?
*(int *)0 = 0;
编译成功
答案 0 :(得分:4)
没有任何意义。那是一个错误。它被解析为
(((int)0) = 0)
因此,试图分配一个右值。在这种情况下,右侧是0
到int
的强制转换(无论如何它已经是一个int)。对某些东西而不是引用的强制转换结果总是一个右值。并且您尝试将0
分配给它。 Rvalues错过的是对象身份。以下方法可行:
int a;
(int&)a = 0;
当然,您可以将其写为以下
int a = 0;
更新:问题格式错误。实际的代码就是这个
*(int*)0 = 0
好吧,现在 是一个左值。但是一个基本的不变量被打破了。标准说
左值是指对象或函数
您指定的左值既不是对象也不是函数。标准甚至明确地说,取消引用空指针((int*)0
创建这样的空指针)是未定义的行为。程序通常会在尝试写入这样一个解除引用的“对象”时崩溃。 “通常”,因为解除引用的行为已经被C ++声明为未定义。
另请注意,上述内容与以下内容不同:
int n = 0;
*(int*)n = 0;
虽然上面写的东西肯定没有找到对象,但是这个会写入将n重新解释为指针的东西。指向值的映射是实现定义的,但是大多数编译器只会在这里创建一个指向地址零的指针。有些系统可能会在该位置保留数据,因此这个系统可能有更多机会保持活力 - 具体取决于您的系统。这个必然不是未定义的行为,但取决于它被调用的编译器和运行时环境。
如果你理解上面的空引用的引用之间的区别(只有值为0的常量表达式转换为指针产生空指针!)和下面重新解释的零值整数,我认为你已经学到了一些重要的东西。
答案 1 :(得分:3)
它通常会在运行时导致访问冲突。完成以下操作:首先将0转换为int *
并生成空指针。然后将值0写入该地址(空地址) - 这会导致未定义的行为,通常是访问冲突。
实际上就是这段代码:
int* address = reinterpret_cast<int*>( 0 );
*address = 0;
答案 2 :(得分:1)
它是一个编译错误。你不能修改非左值。
答案 3 :(得分:1)
它将地址零置零。在某些系统上,您可以执行此操作。大多数基于MMU的系统在运行时都不允许这样做。我曾经看过嵌入式操作系统在执行时间(NULL)时写入地址0。
答案 4 :(得分:0)
该操作中没有有效的左值,因此不应编译。
作业的左侧必须是......错误...可分配