类C语言没有NULL?

发布于 2024-08-19 23:19:52 字数 429 浏览 4 评论 0原文

大家好,我最近在观看一个旧的视频 关于空指针如何造成十亿美元的错误。他指出 C# 和 java 都有运行时检查,但并没有完全消除它,这是可以理解的。他还曾一度指出 C 是一个很大的问题。我发现以 null 结尾的字符串、没有长度的数组以及其他一些东西都很糟糕(缓冲区溢出漏洞利用了数十亿美元),但是要完全删除 null 吗?

有些语言已经使 null 成为过去,而其他语言则试图替代 C,但我找不到哪种语言同时实现了这两点。

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

Hi I was recently watching an old video about how null pointers were a billion dollar mistake. He points out both C# and java as they have run-time checks but don't completely eliminate it enough and this is somewhat understandable. He also points out the C at one point which he feels so sure of is a great problem. I get that null terminated strings, arrays with no length and a few other things are bad (billions of dollars on buffer overflow exploits) but to completely remove null?

Some languages have made null a thing of the past and other languages have attempted at being a replacement for C but I cannot find which language has accomplished both.

If C's null is so bad then why hasn't anyone created it's replacement? i.e. Haskell is nice but cannot operate as a drop in replacement.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

往日 2024-08-26 23:19:52

它没有被替换是有原因的,这样看,C 程序有如此庞大的基础,成千上万的代码散落在各处,创建一个替换会导致很多悲伤,因为代码会进行更新以反映更改,因为指针上下文中的 NULL 意味着调用将失败,因此返回 NULL 来表示代码的条件处理指针失败。此外,它还用于 FILE * 操作,如果文件无效,将返回 NULL。想象一下,如果所有这些代码都被更改,会有多么麻烦,不幸的是,它是 ANSI C 标准的一部分,因此,要更改所有这些代码以适应 NULL 替换的新约定,这将是一项非常昂贵的工作。

看看C 常见问题解答。

编辑:
顺便说一句,“我发现以 null 结尾的字符串、没有长度的数组和其他一些东西都很糟糕”这是错误的说法,因为你混淆了两者......正如 Peter Van Der Linden 《专家 C 编程 - 深度 C 秘密》一书的作者,带有一个 l 的 nul 是“\0”,带有两个 l 的 null 是 NULL!没有诸如 null 终止之类的东西,应该读作 null 终止,即“\0”,它是表示字符串结尾的占位符。

希望这有帮助,
此致,
汤姆.

There is a reason why it was not replaced, look at it this way, there is such a huge wide base of C programs, thousands upon thousands of code lying around, to create a replacement would cause a lot of grief as the code would have to be updated to reflect the change, as a NULL in the context of a pointer means that the call would have failed and hence return a NULL to signify the condition that the code to deal with the pointer has failed. Also, it is used in the case of FILE * operations, if the file was invalid, NULL would be returned. Imagine the hassle if all those code would be changed, unfortunately, it is part of the ANSI C Standard and therefore a very costly exercise in terms of $$$ to get all this changed to adapt to a new convention for a NULL-replacement.

Have a look at this FAQ on the infamous NULL pointer as found in the C FAQ.

Edit:
By the way, 'I get that null terminated strings, arrays with no length and a few other things are bad' That is a wrong way of saying it as you are confusing the two...as Peter Van Der Linden author of 'Expert C Programming - Deep C Secrets', a nul with one l is a '\0', a null with two l is a NULL! No such thing as null terminated, that should have read as nul terminated i.e. '\0' which is a placeholder to signify end of string.

Hope this helps,
Best regards,
Tom.

电影里的梦 2024-08-26 23:19:52

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

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

The problem with null pointers in C is that when you reference them, the program behaves in undefined ways, which results in the "innumerable errors, vulnerabilities, and system crashes" the presentation mentions. But that doesn't mean the idea of a value that is not a real value is necessarily bad. Many languages contain them; they are called NULL, None, NaN, undef, null, nil, etc. You just need to have a well-defined and robust way to deal with them.

I suppose the reason why a language "like C but doesn't crash on null pointer dereferencing" has not seen wide adoption is that the niche for such a language would be very small. One the one hand, you have systems programming where you (purportedly) need tight control over everything that is going on and cannot afford the compiler inserting an automatic null pointer check at every pointer dereference. On the other hand, there is application and other less performance critical programming, where it's much easier to move up a layer or more of abstraction and forget about pointers altogether, which results in things like Java, C#, Python, and others.

爱你不解释 2024-08-26 23:19:52

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

When you say C like, it goes to same direction as others. Scala somehow eliminates nulls using option cases. Still, you can use nulls. Functinal languages have no null problems and side effects but they are not c like. Dynamic languages also have nulls or undefined variables and such.
It is a price you need yo pay for c like imho.

独享拥抱 2024-08-26 23:19:52

任何允许指针数组之类的语言都必​​须考虑到这样的事实:在确定其他元素的合理值之前,可能需要读取某些元素。这增加了代码可能在确定合理值之前尝试读取数组元素的可能性。有三种可能的方法来处理这个问题:

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

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

Any language which allows for things like arrays of pointers must allow for the fact that it may be necessary to read some elements before a sensible value can be ascertained for some others. This raises the possibility than code might attempt to read from an array element before a sensible value has been ascertained for it. There are three plausible ways of handling this:

  1. A compiler may require that every element be written (probably in order) before any can be read; this may waste time writing elements with nonsensical values if sensible ones will not be available until after parts of the array have been read.
  2. An attempt to read an array slot which has not been written may trigger an immediate error, without there being any means of testing whether an array slot is valid, or marking an array slot as being invalid (in case code knows that a certain spot which had been written once should not be read until it has been written again).
  3. As above, but with explicit methods provided for testing whether an array slot is valid, or for invalidating previously-written slots.
  4. An attempt to read an array slot which has not been written or is otherwise invalid will yield a special value which cannot be used for anything except to test validity or to invalidate an array slot or other variable.

While #1 might be nice in some contexts, in many other contexts there isn't any particular value a program could put into array slots which would work better than null.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文