【问题标题】:C-like language without NULL?没有NULL的类C语言?
【发布时间】:2010-01-31 20:32:21
【问题描述】:

嗨,我最近在看一个旧的video,关于空指针是如何造成十亿美元的错误。他指出 C# 和 java 都有运行时检查,但没有完全消除它,这在某种程度上是可以理解的。他还指出了一个他认为非常确定的 C 是一个大问题。我得到了以 null 结尾的字符串、没有长度的数组和其他一些不好的东西(数十亿美元的缓冲区溢出漏洞利用),但是要完全删除 null?

一些语言已经让 null 成为过去,而其他语言也试图替代 C,但我找不到哪一种语言同时实现了这两个目标。

如果 C 的 null 如此糟糕,那么为什么没有人创建它的替代品?即 Haskell 很好,但不能作为替代品运行。

【问题讨论】:

  • 语言和平台也有惯性。
  • 恕我直言,根据定义,没有 NULL 的语言不会像 C。
  • 很多语言都没有这个 NULL 问题。他们只是不像C。如果您想摆脱 NULL,那么请克服您对 C 的依赖并使用另一种语言。
  • @RBarryYoung - 我真的不明白那条评论想要做什么。我承认存在其他类似 c 的语言和没有 null 的语言。使用 C 不是上瘾。

标签: null computer-science language-design nullable


【解决方案1】:

不被替换是有原因的,这样看,C程序库如此庞大,代码成千上万,创建替换会引起很多悲痛,因为代码必须更新以反映更改,因为指针上下文中的 NULL 意味着调用将失败,因此返回 NULL 以表示处理指针的代码已失败的情况.此外,它用于FILE * 操作的情况下,如果文件无效,将返回NULL。想象一下,如果所有这些代码都被更改会很麻烦,不幸的是,它是 ANSI C 标准的一部分,因此在 $$$ 方面进行非常昂贵的练习,以使所有这些更改以适应 NULL 替换的新约定。

查看有关C FAQ 中臭名昭著的 NULL 指针的常见问题解答。

编辑: 顺便说一句,'我得到空终止的字符串,没有长度的数组和其他一些东西是不好的'这是一种错误的说法,因为你混淆了两者......就像彼得Van Der Linden 《Expert C Programming - Deep C Secrets》一书的作者,一个带有一个 l 的 nul 是一个 '\0',一个带有两个 l 的空值是一个 NULL!没有 null 终止之类的东西,它应该读作 nul 终止,即 '\0' 这是一个表示字符串结束的占位符。

希望这会有所帮助, 最好的祝福, 汤姆。

【讨论】:

    【解决方案2】:

    C 中空指针的问题在于,当您引用它们时,程序会以未定义的方式运行,这会导致演示文稿中提到的“无数错误、漏洞和系统崩溃”。但这并不意味着价值不是真实价值的想法一定是坏的。许多语言都包含它们;它们被称为 NULL、None、NaN、undef、null、nil 等。您只需要有一个定义明确且健壮的方法来处理它们。

    我认为“类似于 C 但不会因空指针取消引用而崩溃”的语言尚未得到广泛采用的原因是这种语言的利基市场非常小。一方面,您在系统编程中(据称)需要严格控制正在发生的所有事情,并且无法让编译器在每个指针取消引用时插入自动空指针检查。另一方面,在应用程序和其他对性能要求不高的编程中,更容易向上移动一层或更多抽象层并完全忘记指针,从而产生 Java、C#、Python 等。

    【讨论】:

      【解决方案3】:

      当你说 C 喜欢时,它与其他人的方向相同。 Scala 以某种方式使用选项案例消除了空值。不过,您可以使用空值。函数式语言没有空问题和副作用,但它们不像 c。动态语言也有空值或未定义的变量等。 这是您需要为 c 支付的价格,例如恕我直言。

      【讨论】:

        【解决方案4】:

        任何允许诸如指针数组之类的东西的语言都必​​须考虑这样一个事实,即在确定其他一些元素的合理值之前可能需要读取一些元素。这增加了代码在确定合理值之前可能尝试从数组元素中读取的可能性。有三种可能的处理方式:

        1. 编译器可能要求先写入每个元素(可能按顺序),然​​后才能读取任何元素;如果在读取数组的某些部分之后才可用,这可能会浪费时间写入具有无意义值的元素。
        2. 尝试读取尚未写入的数组槽可能会立即触发错误,但无法测试数组槽是否有效,或将数组槽标记为无效(如果代码知道某个已经写过一次的地方,在再次被写之前不应该被阅读)。
        3. 如上所述,但提供了用于测试数组槽是否有效或使先前写入的槽无效的显式方法。
        4. 尝试读取尚未写入或无效的数组槽将产生一个特殊值,该值不能用于任何事情,除非测试有效性或使数组槽或其他变量无效。

        虽然 #1 在某些情况下可能很好,但在许多其他情况下,程序无法将任何特定值放入数组槽中,这会比 null 更好。

        【讨论】:

          猜你喜欢
          • 2017-07-31
          • 1970-01-01
          • 1970-01-01
          • 2023-01-16
          • 1970-01-01
          • 2010-09-22
          • 1970-01-01
          • 1970-01-01
          • 2021-12-15
          相关资源
          最近更新 更多