问题描述
1。是否定义了NULL - NULL
?
-
是否已定义
(char *)NULL - (char *)NULL
?? -
是否定义了
(uintptr_t)NULL - (uintptr_t)NULL
?
我知道它可以在我使用的所有实现中使用。但是从标准的角度来看,它是什么样的呢?我找不到明确的答案。
编辑: 从这个骗子中,我认为问题的答案是:是的。
第二个和第三个问题呢?
解决方法
C标准文档NULL
被定义为宏,该宏扩展为实现定义的空指针常量
根据实际定义,表达式NULL - NULL
可以具有定义的值,也可以没有。例如:
- 如果将
NULL
定义为#define NULL 0
,则NULL - NULL
实际上是类型为int
且值为0
的常量表达式。 - 如果将
NULL
定义为#define NULL ((void *)0)
,则表达式NULL
违反了约束,因为没有在空指针上定义算术。
第二个问题:是(char*)NULL - (char*)NULL
还是(uintptr_t)NULL - (uintptr_t)NULL
?。这些表达式不再违反约束:
-
由于从
void *
到算术类型的转换是实现定义的,因此(uintptr_t)NULL - (uintptr_t)NULL
的值什么也不能说。在大多数当前系统上,它将是0
,但是C标准没有对其进行定义。 -
转换为
(char *)
的情况稍有不同:仅当两个指针指向同一数组或指向数组最后一个元素之后的位置时,才定义2个指针的区别此讨论的一个元素数组。在(char *)NULL
中不是这种情况,它是一个空指针,因此不指向任何数组或对象。