将int类型的变量地址赋值给它本身的值

27

以下代码是未定义行为、实现定义行为还是由标准定义的?我找不到有关将整数分配给其自身地址的参考资料。

volatile int x = (int)&x;

这段代码被翻译成:

lea         eax,[ebp-4]  
mov         dword ptr [ebp-4],eax 

2
我认为这归结于如何处理将地址转换为整数。我认为它存储在整数本身中并不重要。 - templatetypedef
1
只要 int 至少和 int * 一样宽,x 的值就会被实现定义;这和你使用 reinterpret_cast 将指针转换为 int 时的情况一样。 - avakar
4
我认为这是由具体实现决定的。在某些平台上,一个 int 可能无法容纳指针(地址)的值。例如,在一个具有 24 位寻址的 16 位字系统中。 - Thomas Matthews
11
著名的C/C++标准? - Pascal Cuoq
2
@DieterLücking 这不是重复的问题。我正在询问编译器在将本地整数分配给自己的地址时的行为,而你指向的问题涉及将地址作为参数提供给函数。 - Yuval
显示剩余7条评论
3个回答

21

在C语言中,声明和初始化同时使用变量" x "是可以的:

(C99, 6.2.1p7) "[...] 其他任何标识符的作用域都是在其声明符完成后开始的。"

将指针转换为整数的结果是由实现定义的,并且可能会导致未定义的行为:

(C99, 6.3.2.3p7) "任何指针类型都可以转换为整数类型。除非另有规定,否则结果是由实现定义的。如果该结果不能表示为整数类型,则行为是未定义的。结果不必在任何整数类型的值范围内。"


11

根据C++的声明点规则,它是明确定义的。因为在=之前,变量x已经被声明,此时&x也已知。

这里有一个棘手的问题,下面的代码属于未定义行为

int x = x;        // undefined behavior, using uninitialized variable

但是...

int x = (int)&x;  // defined behavior

我在谈论C ++,但我认为这对C也适用。


2
在您展示的ASM代码中,指针的值首先被放入eax中,然后从eax读取指针,并将其放入与整数值相同的位置。
唯一的问题在于,int并不总是与int*大小相同。在我的64位机器上,int为4个字节,而指针为8个字节。如果我在我的电脑上运行您的代码,我只会得到指针的一半。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接