【发布时间】:2012-12-23 18:44:10
【问题描述】:
C 允许将NULL 定义为任何空指针常量,换句话说,任何计算结果为0 的整型常量表达式,或这样的表达式转换为void *。我的问题涉及定义的选择是否真的很重要,即是否正确的程序可能取决于使用的定义。出于这个问题的目的,我想忽略诸如 NULL 被传递给可变参数函数或缺少原型的函数之类的问题,因为我已经单独处理了它。让我们假设sizeof NULL == sizeof(void *) 和sizeof NULL == sizeof(T) 是某个整数类型T,因此sizeof 不足以回答NULL 是否具有指针类型的问题。
显然,C11 提供了一种区分 NULL 或任何其他表达式类型的方法:_Generic 关键字。
C99 还提供了一种看似可靠的晦涩方式:
int null_has_ptr_type()
{
char s[1][1+(int)NULL];
int i = 0;
return sizeof s[i++], i;
}
有没有其他方法可以通过符合标准的 C 程序来确定 NULL 的类型?在 C89 中可以使用吗?
【问题讨论】:
-
char c = NULL;如果NULL的类型为void *(因此存在转换),则生成编译器警告。 -
函数
null_has_ptr_type真的有用吗?它在我的计算机上两种情况下都返回 0。 -
return sizeof s[i++], i;将返回 i。 -
在这种情况下,您需要一个支持 C99 的 C 编译器,包括 VLA 和 sizeof 的正确实现。如果
s是VLA,则评估i++,否则不是。如果 NULL 是指针,s将是 VLA,而不是 int。或者类似的东西...... GCC 在这两种情况下都会给出不同的警告。 @Kirilenko -
@R..: gcc.gnu.org/gcc-4.4/c99status.html 声明“损坏”VLA 支持。 4.5说没问题。 (4.6.1 有效。)
标签: c language-lawyer