3 ms·
By the way, null-terminated strings are not the only way to express strings, it’s a legacy of C that many low-level programmers dislike but need to stick to it
by cyber_kinetist 4y ago
By the way, null-terminated strings are not the only way to express strings, it’s a legacy of C that many low-level programmers dislike but need to stick to it because of legacy reasons (every major OS is written in C).
All the low-level languages aiming to replace C basically abandoned this approach, and opted for slices instead (ptr + size pair, used in Rust, Zig, etc.) This has the benefit of easier and faster string manipulation (strlen can be O(1) instead of O(n)), as well as better memory safety (can do bounds checking with the size information). The primary reason we are still using and teaching null terminators is because we still have to live with POSIX/Win32 and many low-level libraries written on this platform.
- stevekemp 4y agoIndeed, I remember Turbo Pascal, running under CP/M, used the scheme where strings where prefixed with their length rather than being NUL terminated.
- rofrol 4y agoI thought zig has null terminated string literals. What's the difference? String literals are constant single-item Pointers to null-terminated byte arrays. The type of string literals encodes both the length, and the fact that they are null-terminated, and thus they can be coerced to both Slices and Null-Terminated Pointers https://ziglang.org/documentation/master/#String-Literals-and-Unicode-Code-Point-Literals https://ziglang.org/documentation/master/#String-Literals-an...
- cyber_kinetist 4y agoHmm... after some research it seems that I've misunderstood Zig's situation a bit. Zig has introduced null-terminated string types a couple of years ago, but still encourages you to do most string operations with slices instead. Let me explain: Zig's string literals (which you create with parenthesis like "Hello world!") are null-terminated byte arrays, expressed as the type *const [N:0]u8 (where the :0 tells you that it's null-terminated), whereas the more typical array might be written as *const [N]u8. The reason for this feature is not because the language wants you to use null-terminated strings, but because these static strings need to be stored in the global data section of the ELF executable, and these require you to use null-termination. But if you want to do any mutable operation with this string, you need to convert this into a proper slice (ptr + size). And it seems like Zig developers don't really use null-terminated types that much at the API level, but use it for things like C interop or cases where you really need it for special optimizations. Noting that from the PR that introduced this feature, Andrew Kelley writes [0]: > I think you will find that the Zig community in general (and especially myself) agrees with you on this [null-terminated strings being fragile], and APIs in general should prefer slices to null terminated pointers. Even if you are using Zig to create a C library, and even in actual C libraries, I would recommend pointer and length arguments rather than null terminated pointers, like this: https://github.com/andrewrk/libsoundio/blob/1.1.0/soundio/soundio.h#L795 https://github.com/andrewrk/libsoundio/blob/1.1.0/soundio/so... > That being said, I want to repeat what I said earlier about null terminated pointers: A null terminated array is not inherently an evil C concept that is intruding in the Zig language. It's a general data storage technique that is valid for some memory constrained use cases. I also stumbled on a Real Actual Use Case inside LLVM. The bottom line for me is that null terminated pointers exist in the real world, and especially in systems programming. You can see this in interfaces with the operating system in the standard library... So he acknowledges null-terminated strings can certainly be useful in certain situations outside of legacy reasons, which is good to know. And Zig creating a special type for this shows that a good systems language needs to be designed to accommodate the needs of the outside world. [0] https://github.com/ziglang/zig/issues/265#issuecomment-463374382 https://github.com/ziglang/zig/issues/265#issuecomment-46337...
- AndyKelley 4y agoThanks for this nice writeup! Small correction regarding the ELF object file format: any kind of data whatsoever can be stored in the data section, including strings in the form of ptr + length without null termination. Zig string literals are null terminated in addition to having the length not because of an object file limitation but because it is useful to pass string literals to APIs that require null-termination, such as most C libraries. In practice, this simplifies the experience of using the language.
- cyber_kinetist 4y agoAh, thanks for the correction.