【问题标题】:Difference in definition of null pointer in C99 and C++03C99和C++03中空指针定义的区别
【发布时间】:2020-12-24 17:11:47
【问题描述】:

N2431 是介绍nullptr 的论文。它说:

当前的 C++ 标准提供了一个特殊规则,即 0 既是整数常量,又是 空指针常量。来自 [C++03] 第 4.10 条:

空指针常量是整数类型的整数常量表达式 (expr.const) 右值 评估为零。空指针常量可以转换为指针类型;结果是 该类型的空指针值,并且可以与指向的所有其他指针值区分开来 对象或指向函数类型的指针。相同类型的两个空指针值应比较相等。 将空指针常量转换为指向 cv 限定类型的指针是一次转换,而不是指针转换后跟限定转换的顺序 (conv.qual)。

此公式基于原始 K&R C 定义,与 C89 和 C99。 C 标准 [C99] 说(第 6.3.2.3 条):

值为 0 的整数常量表达式,或转换为 void * 类型的此类表达式是 称为空指针常量。 [55]如果将空指针常量转换为指针类型,则 结果指针,称为空指针,保证比较不等于指向任何指针的指针 对象或函数。

让我们忽略“[c++03] 公式化是基于原始 K&R C 定义”部分,重点关注“[c++03 公式化] 与 [...] C99 中的定义不同”。

我不清楚 C++03 和 C99 的定义有何不同。是的,他们在书面标准中有不同的正式定义(我们可以看到引用不同),但从实际角度来看这意味着什么?他们真的有区别吗?如果我没有正确阅读这篇文章,那么它的语气暗示存在差异。如果是这样,它们是什么?我无法理解/理解基于标准引用的差异。

我没有具体询问 C++03 或 C99 空指针是如何定义、表示和/或实现的。我的问题是关于 C++03 和 C99 空指针定义(可能还有它们的实现,如果这对回答这个问题很重要的话)有何不同,答案可以包含对 C++03 和C99 空指针,但仅作为一个帮助点来展示差异或显示差异。也就是说,仅提供定义或对每个定义的解释不被视为该问题的答案。

我完全清楚nullptr 是在 C++11 及更高版本中表达空指针的首选方式。这不是问题。

【问题讨论】:

  • 似乎 C++03 的措辞被删除了 "或这样的表达式转换为类型 void *"。所以static_cast<void*>(0) 显然不会算作空指针常量,而0 会算作空指针常量。

标签: c++ c language-lawyer c99 c++03


【解决方案1】:

标准不允许 (void*)0 作为空指针常量的原因是 void* 不能转换为任何其他指针类型(除了 cv 限定的 void*)。在 C 语言中,您可以使用 void *p = 0; int *ip = p;。在 C++ 中,不允许隐式转换为 int*

【讨论】:

    【解决方案2】:

    在 C 中你有

    值为 0 的整数常量表达式,或转换为 void * 类型的此类表达式

    这意味着具有0(void*)0 值的整数常量是有效的空指针常量。

    在 C++ 中你有

    空指针常量是整数类型的整数常量表达式 (expr.const) 右值,其计算结果为零

    这意味着只有值为0 的整数常量才是有效的空指针常量。

    【讨论】:

    • 也许你的意思是写(void*)0而不是void*(0)
    • @AveMilia 是的,已修复
    • 也许您可以另外解释 C++03(或更早,如果适用)标准将指向 void 的指针作为有效的空指针表示的基本原理?这是为了改进 C++ 类型系统,为编译器引入优化的机会,还是别的什么?
    • @NathanOliver:我认为原因更简单:如果NULL 定义为((void*)0),则不能隐式转换为其他指针类型:char *p = NULL; 需要转换为char *p = (char *)NULL;如果缺少 (void*) 演员表,这不是问题。
    • @chqrlie 正确。 int 在 C 中,char 在 C++ 中。删除了我不完整的评论。
    猜你喜欢
    • 2011-04-04
    • 2019-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多