【问题标题】:Assigning 0 vs NULL to a pointer in C将 0 vs NULL 分配给 C 中的指针
【发布时间】:2018-01-16 19:05:59
【问题描述】:

今天我想知道是否可以将整数 0 分配给指针,即执行与分配 NULL 相同的操作。直到今天我都认为,这是 C++ 的新功能。这从一开始就是 C 的一个特性,还是随着更新的语言标准而放松?

【问题讨论】:

  • 指针指向内存地址。 0 是有效的无效内存地址
  • "可以将整数 0 分配给指针" 对于 object 指针是可以的。不确定函数指针——它们有一些不同的规则。
  • 实际上,在我所知道的任何现代硬件和操作系统上,从地址 0 开始的内存页面在 MMU 中被有意取消映射,因此任何取消引用那里的指针的尝试总是会产生页面错误,这通常会映射到操作系统级别的致命错误。
  • @DanielPryden Minor:标准不调用 0 literal,而是 constant
  • @DanielPryden:现代操作系统将地址 0 标记为未映射到 用户空间。在内核空间中不一定如此。 C 支持“独立环境”(特殊情况)以及“托管环境”(普通用户程序)。我知道内存被映射为零对于某些内核代码来说是个问题。地址 0 不用于任何 C 对象,因此它满足空指针与指向有效对象的指针可区分的规则,但这意味着空指针的不正确解引用不会崩溃,使得一些 bug 难以发现。

标签: c null-pointer


【解决方案1】:

Per The C Programming Language,Kernighan 和 Ritchie,1978 年,第 192 页:

但是,可以保证将常量 0 分配给指针将产生一个空指针,该指针可与指向任何对象的指针区分开来。

在那之前我无法谈论历史。

【讨论】:

    【解决方案2】:

    根据 C 标准(6.3.2.3 指针)

    3 值为 0 的整数常量表达式,或者这样的 将表达式强制转换为 void *, 称为空指针 常量.66) 如果一个空指针常量被转换为一个指针 类型,结果指针,称为空指针,保证 比较不等于指向任何对象或函数的指针。

    【讨论】:

    • 主要问题的好答案。您对“这是从一开始就成为 C 语言的一个特性还是放松了”的想法?
    • 至少在早期版本中,它不是“c”的广告功能。尽管它在大多数情况下都有效。因此定义了 NULL 以使其完全可移植。
    • @Serge:是什么让你认为它不是 C 早期版本的特性?多早?它似乎在C 1989 中,根据我的回答,在 K&R 1978 中。
    • @EricPostpischil 这是我的回忆。据我所知,有些平台未将 NULL 定义为 (void*)0
    • @Serge NULL 的定义与“可以将整数 0 分配给指针”无关 NULL 可能在数值上和/或type 来自0(根据你和我的记忆),但ptr1 = 0; ptr2 = NULL; 都分配了一个空指针。分配的 空指针 可能具有不同的位模式,但它们作为指针进行比较。
    【解决方案3】:

    在 K&R 第一版(ANSI 之前)第 97-98 页中,我们有一些示例代码:

    #define NULL 0 /* pointer value for error report */
    

    "C 保证有效指向数据的指针不会包含 零,因此返回值零可用于表示异常事件……但是,我们用 NULL 代替零,以更清楚地表明这是指针的特殊值。一般来说,整数不能有意义地分配给指针。”

    很明显这里0,因此NULL,不是作为指针类型而是int。值得注意的是,void * 直到第 2 版 (ANSI) 才引入。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-06
      • 1970-01-01
      • 2013-12-10
      • 2015-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多