我知道这是个奇怪的问题,但只是很好奇。
char* ptr = 0;
strcpy( (char*) &ptr, "UB?");
这段代码的意思是“我将使用 ptr 的内存作为 char 数组。” 我认为“这绝对是 UB”,但有人说“除非你取消引用,否则它不是 UB”。 这不是UB吗?这么糟糕的代码怎么能不UB呢?
C17 §6.5 第 6 段包括:
访问其存储值的对象的“有效类型”是该对象的声明类型(如果有)。 [...]
ptr
表示的对象的有效类型是
char *
。第 7 段包括:
对象的存储值只能由具有以下类型之一的左值表达式访问:
与对象的有效类型兼容的类型,
由
- 与对象的有效类型兼容的类型的限定版本,
- 一个类型,即与对象的有效类型对应的有符号或无符号类型,
- 与对象有效类型的限定版本相对应的有符号或无符号类型的类型,
- 在其成员中包含上述类型之一的聚合或联合类型(递归地包括子聚合或包含联合的成员),或者
- 字符类型。
ptr
表示的对象的存储值由字符类型的左值表达式访问(通过
strcpy
函数,该函数将字符解释为具有 unsigned char
类型)。这不是UB。union {
char arr[4];
char *ptr;
} trouble;
strcpy( trouble.arr, "UB?" );
void**
用作“指向任何数据指针的指针”类型,以访问用于保存任何数据指针的存储,但它不允许使用
unsigned char*
或用于此类目的的其他类似类型。我不知道除 CompCertC 之外的任何正式指定的方言都不允许通过 unsigned char*
或类似类型操作指针表示。