不,它不是有效的 C,并且从来都不是有效的 C。这些例子是所谓的违反约束标准的。
该标准不允许您将指针初始化/分配给整数,也不允许将整数初始化/分配给指针。您需要使用强制类型转换手动强制类型转换:
int* p = (int*) 0x1234;
int i = (int)p;
如果您不使用强制转换,则代码不是有效的 C,并且您的编译器不允许在不显示消息的情况下让代码通过。转换运算符声明:C17 6.5.4/3:
约束条件
/--/
除 6.5.16.1 的约束允许的情况外,涉及指针的转换应通过显式强制转换来指定。
6.5.16.1 的规则简单的作业允许对指针进行某些隐式转换,请参阅 C17 6.5.16.1 §1:
6.5.16.1 简单赋值
约束条件
应满足下列条件之一:
- 左操作数具有原子、限定或非限定算术类型,右操作数具有
算术类型;
- 左操作数具有结构或联合类型的原子、限定或非限定版本
与权利类型相兼容;
- 左操作数具有原子、限定或非限定指针类型,并且(考虑类型
左操作数在左值转换后将具有)两个操作数都是指向限定的指针
或兼容类型的非限定版本,并且左侧指向的类型具有所有
右侧指向的类型的限定符;
- 左操作数具有原子、限定或非限定指针类型,并且(考虑类型
左操作数在左值转换后将具有)一个操作数是指向对象类型的指针,
另一个是指向 void 的限定或非限定版本的指针,以及指向的类型
左边有右边指向的类型的所有限定符;
- 左操作数是原子、限定或非限定指针,右操作数是空指针
持续的;或者
- 左操作数的类型为原子、限定或非限定 _Bool,右操作数是指针。
的情况下int* p = 0x12345678;
,左操作数是指针,右操作数是算术类型。
的情况下int i = p;
,左操作数是算术类型,右操作数是指针。
这些都不符合上述任何限制。
至于为什么int* p = 0;
有效,这是一个特殊情况。左操作数是指针,右操作数是空指针常量. 有关空指针、空指针常量和 NULL 宏之间差异的更多信息.
一些注意事项:
An integer may be converted to any pointer type. Except as previously specified, the
result is implementation-defined, might not be correctly aligned, might not point to an
entity of the referenced type, and might be a trap representation. 68)
任何指针类型都可以转换为整数类型。除先前指定的情况外,结果
是实现定义的。如果结果不能用整数类型表示,则行为是
不明确的。结果不必在任何整数类型的值范围内。
信息脚注:
68) The mapping functions for converting a pointer to an integer or an integer to a pointer are intended to be consistent with the addressing structure of the execution environment.
此外,指针的地址可能比指针所能容纳的地址大。int
,就像大多数 64 位系统的情况一样。因此最好使用uintptr_t
from <stdint.h>