# Null consistency

**URL:** <https://internals.rust-lang.org/t/null-consistency/16767>\
**Category:** libs\
**Created:** [June 7, 2022, 9:23pm UTC](https://internals.rust-lang.org/t/null-consistency/16767 "2022-06-07T21:23:53Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [June 7, 2022, 9:23pm UTC](https://internals.rust-lang.org/t/null-consistency/16767/1 "2022-06-07T21:23:53Z")

</div>

We have `ptr::null` and `ptr::is_null`, but `CStr::from_bytes_with_nul` and "nul-terminated" strings.

I think it would be more consistent to replace (deprecate and reëxport) all instances of `nul` with `null`.

What do you all think? If we have rough consensus here, I'll prepare a PR for T-libs-api FCP.

---

<div class="post-metadata">

**Author:** ![josh](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/josh/32/5934_2.png) [@josh](https://internals.rust-lang.org/u/josh)\
**Post date:** [June 7, 2022, 9:30pm UTC](https://internals.rust-lang.org/t/null-consistency/16767/2 "2022-06-07T21:30:09Z")

</div>

`nul` and `null` are two different things. `null` is a pointer to address 0, while `nul` is the name of the character with value 0.

That distinction is sometimes elided (people often say "null-terminated" rather than "nul-terminated"), but that's the distinction the API names are based on.

---

<div class="post-metadata">

**Author:** ![mjbshaw](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mjbshaw/32/5103_2.png) [@mjbshaw](https://internals.rust-lang.org/u/mjbshaw)\
**Post date:** [June 7, 2022, 9:30pm UTC](https://internals.rust-lang.org/t/null-consistency/16767/3 "2022-06-07T21:30:18Z")

</div>

IIRC "NUL" is the abbreviation blessed by ASCII/Unicode for the null character. I'm not sure how I feel regarding the proposal, but a part of me likes that we can differentiate between NUL (the character) and null (the pointer).

---

<div class="post-metadata">

**Author:** ![jhpratt](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jhpratt/32/11640_2.png) [@jhpratt](https://internals.rust-lang.org/u/jhpratt)\
**Post date:** [June 7, 2022, 10:25pm UTC](https://internals.rust-lang.org/t/null-consistency/16767/4 "2022-06-07T22:25:06Z")

</div>

I think a doc alias should suffice, as the two aren't _quite_ the same as already stated.

---

<div class="post-metadata">

**Author:** ![jdahlstrom](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/jdahlstrom/32/3351_2.png) [@jdahlstrom](https://internals.rust-lang.org/u/jdahlstrom)\
**Post date:** [June 8, 2022, 1:17am UTC](https://internals.rust-lang.org/t/null-consistency/16767/5 "2022-06-08T01:17:51Z")

</div>

The similarity of the established terms is unfortunate, but the distinction is important. `from_bytes_with_null` would confuse me because in my mind "null" always means a null pointer.

---

<div class="post-metadata">

**Author:** ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)\
**Post date:** [June 8, 2022, 2:11am UTC](https://internals.rust-lang.org/t/null-consistency/16767/6 "2022-06-08T02:11:52Z")

</div>

> [@CAD97](#):
>
> replace (deprecate and reëxport)

I'm really not convinced it's worth it. The "did you mean?" hint for it should be nigh perfect if you try `ptr::nul`

```plaintext
error[E0425]: cannot find function `nul` in module `std::ptr`
   --> src/main.rs:2:15
    |
2 | std::ptr::nul();
    | ^^^ help: a function with a similar name exists: `null`

```

or `from_bytes_with_null`

```plaintext
error[E0599]: no function or associated item named `from_bytes_with_null` found for struct `CStr` in the current scope
 --> src/main.rs:3:11
  |
3 | CStr::from_bytes_with_null();
  | ^^^^^^^^^^^^^^^^^^^^
  | |
  | function or associated item not found in `CStr`
  | help: there is an associated function with a similar name: `from_bytes_with_nul`

```

And that seems fine to me.

* * *

Note that, according to [https://www.unicode.org/Public/14.0.0/ucd/UnicodeData.txt](https://www.unicode.org/Public/14.0.0/ucd/UnicodeData.txt), the name of U+0000 is "NULL", not "NUL":

```plaintext
0000;<control>;Cc;0;BN;;;;;N;NULL;;;;
0001;<control>;Cc;0;BN;;;;;N;START OF HEADING;;;;
0002;<control>;Cc;0;BN;;;;;N;START OF TEXT;;;;

```

Though admittedly [https://www.unicode.org/Public/14.0.0/ucd/NameAliases.txt](https://www.unicode.org/Public/14.0.0/ucd/NameAliases.txt) does list `NUL` as an "abbreviation"

```plaintext
0000;NULL;control
0000;NUL;abbreviation
0001;START OF HEADING;control
0001;SOH;abbreviation

```

But that does mean that `null` is a perfectly correct way to refer to U+0000, not something that only means the null pointer. (Arguably the non-abbreviation is generally better, as elaborated [0580-rename-collections - The Rust RFC Book](https://rust-lang.github.io/rfcs/0580-rename-collections.html#why-prefer-full-names-when-in-doubt), but I suppose abbreviations do make sense in method names because `print_with_line_feed` is a bit excessive compared to `print_with_lf`.)

---

<div class="post-metadata">

**Author:** ![lordan](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lordan/32/2107_2.png) [@lordan](https://internals.rust-lang.org/u/lordan)\
**Post date:** [June 9, 2022, 1:08pm UTC](https://internals.rust-lang.org/t/null-consistency/16767/7 "2022-06-09T13:08:43Z")

</div>

> [@scottmcm](#):
>
> But that does mean that `null` is a perfectly correct way to refer to U+0000

Yes, but the 0-byte at the end of a `CStr` is just that : a byte in a series of (otherwise non-0) bytes, not a UTF-8 encoding. Thus the naming follows the ASCII convention (or perhaps even preceding ASCII?):

| # | Abbr. | Description | | # | Abbr. | Description |
| --- | --- | --- | --- | --- | --- | --- |
| 0 | NUL | Null | | 16 | DLE | Data Link Escape |
| 1 | SOH | Start of Header | | 17 | DC1 | Device Control 1 |
| 2 | STX | Start of Text | | 18 | DC2 | Device Control 2 |
| 3 | ETX | End of Text | | 19 | DC3 | Device Control 3 |
| 4 | EOT | End of Transmission | | 20 | DC4 | Device Control 4 |
| 5 | ENQ | Enquiry | | 21 | NAK | Negative Acknowledge |
| 6 | ACK | Acknowledge | | 22 | SYN | Synchronize |
| 7 | BEL | Bell | | 23 | ETB | End of Transmission Block |
| 8 | BS | Backspace | | 24 | CAN | Cancel |
| 9 | HT | Horizontal Tab | | 25 | EM | End of Medium |
| 10 | LF | Line Feed | | 26 | SUB | Substitute |
| 11 | VT | Vertical Tab | | 27 | ESC | Escape |
| 12 | FF | Form Feed | | 28 | FS | File Separator |
| 13 | CR | Carriage Return | | 29 | GS | Group Separator |
| 14 | SO | Shift Out | | 30 | RS | Record Separator |
| 15 | SI | Shift In | | 31 | US | Unit Separator |

---

<div class="post-metadata">

**Author:** ![felix.s](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/felix.s/32/8073_2.png) [@felix.s](https://internals.rust-lang.org/u/felix.s)\
**Post date:** [July 10, 2022, 10:08am UTC](https://internals.rust-lang.org/t/null-consistency/16767/8 "2022-07-10T10:08:01Z")

</div>

I have been annoyed by people speaking of ‘`NULL`-terminated strings’ and writing `char c = NULL;` enough times to appreciate, for once, a programming language clearly distinguishing the pointer to nothing from code point zero. They are named differently because they are different things, and it’s about time people learned that.

(Relatedly, about the only thing I like about Go is that it named its Unicode scalar value type ‘rune’, in order to distance the programmer, if only just slightly, from the misconception that Unicode scalars are isomorphic to ‘characters’.)

> [@scottmcm](#):
>
> Note that, according to [https://www.unicode.org/Public/14.0.0/ucd/UnicodeData.txt](https://www.unicode.org/Public/14.0.0/ucd/UnicodeData.txt), the name of U+0000 is "NULL", not "NUL":

Well, not quite. C0 and C1 control codes don’t officially have names in Unicode, only formal aliases; they had names in version 1.0, but those were withdrawn in version 1.1, and control character aliases were introduced only in version 6.1. The field you are pointing at in the UnicodeData.txt file is the ‘Unicode 1.0 name’ (property `Unicode_1_Name`, `na1`). This is what allowed the introduction of U+1F514 BELL in Unicode 6.0, despite U+0007 being known under that name in version 1.0.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [October 8, 2022, 10:08am UTC](https://internals.rust-lang.org/t/null-consistency/16767/9 "2022-10-08T10:08:02Z")

</div>

Closed on October 8, 2022, 10:08am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
