4 ms·
> No objects, just structs C doesn't have 'objects' either, just structs. In Zig you can add functions to structs though, and you have UFCS syntax sugar, both
by flohofwoe 4y ago
> No objects, just structs
C doesn't have 'objects' either, just structs.
In Zig you can add functions to structs though, and you have UFCS syntax sugar, both together is pretty close to class methods ;)
Those sentinel terminated arrays are a killer feature for C API interop, since you don't need to allocate separate C strings on the stack or heap just for passing string literals into the C API (Zig string literals are such sentinel-terminated arrays, so they are both slices and zero-terminated for C string compatibility). I really wish Rust would use the same idea, it would simplify creating C API wrappers a lot.
One of my favourite features of Zig is actually the arbitrary width integers, C23 is getting those too though.
...and in general Zig is fixing all the 'sloppy parts' of C, for instance it's very rigorous about not allowing implicit conversions which would lose data (e.g. trying to assign an u8 to an i8 is an error, u7 to i8 is allowed though, because no data would be lost).
PS: also how could I forget about the comptime features, this is for instance an area which is ignored by many other attempts of creating a better C, but one of the core features of Zig.
- hawski 4y agoI think one of the author's problems is that he conflates C and C++ and it seems they do not have a knowledge around either. This quote also supports this: > There is no malloc keyword like in C/C++.
- T-A 4y agoAre you nitpicking about it being a keyword in C, https://en.cppreference.com/w/c/memory/malloc https://en.cppreference.com/w/c/memory/malloc and a standard library function in C++ https://en.cppreference.com/w/cpp/memory/c/malloc https://en.cppreference.com/w/cpp/memory/c/malloc ?
- tialaramex 4y agoThat's not a keyword. It's just a free function, maybe you could argue it is an intrinsic since it's magic and needs to some extent to be blessed by the implementation (It is conjuring things from "nowhere" in the higher level language, obviously normal functions aren't supposed to just make objects, only transform them - but this can, so that's magic)
- T-A 4y agoAh yes, you're right, it's not strictly speaking a keyword in either one.
- hawski 4y agoIt is not a keyword in C, so it is not a nit. For all the language is concerned it is just a function that takes a number and returns a pointer. If a compiler treats it any different it is only a question of optimizations or to generate helpful warning/error messages. You can point linker to a different implementation for all it cares.
- gpderetta 4y agoTechnically C has objects. That's any chunk of memory with a type, size, alignment and duration. Incidentally C++ has exactly the same definition. Just being pedantic, nothing to see here.
- Karellen 4y ago> That's any chunk of memory with a type, size, alignment and duration. Isn't that just "a variable"?
- gpderetta 4y agoint * int_ptr = malloc(sizeof(int)); int_ptr is a variable (and also an object), the pointed to memory is an object but not a variable.
- smcl 4y agoI think the point is that the C standard (or K&R, or both? I forget) repeatedly refers to "objects", and uses the word differently than we're used to in OOP
- oriolid 4y agoC++ has syntax for adding functions to objects and type system support for deriving object types from other object types and overriding those member functions. There are some who consider these a rather important thing.
- gpderetta 4y agoI'm just saying that, pedantically, "object" is a term of art in C and C++ which has little to do with the typical OOP definition of object.
- tialaramex 4y agoIndeed. For example the language needs a notion of these objects having some particular type, and they need to be able to have lifetimes, so that we can talk about ideas like type punning (legal in C in some ways, not legal in C++), about aliasing rules, and about provenance. If you don't want to do any of this, you can't achieve the performance from high level software (where "high level" here means C rather than machine code) that people have come to expect and demand.
- tialaramex 4y ago> I really wish Rust would use the same idea, it would simplify creating C API wrappers a lot. Zero terminated strings suck, you need to do allocation everywhere to work with them, or else you must in-place mutate the strings in hard to reason about ways and they can't fully represent arbitrary text. So I definitely wouldn't want Rust's &str string references to have either behaviour. If what you do is interact closely with C wrappers, Rust of course provides a type for this: std::ffi::CString and that's fine, but it is a miserable structure to use for actual string work.
- flohofwoe 4y agoWell yeah, zero terminated strings suck, but that doesn't change the fact that pretty much all operating systems and fundamental C libraries expect strings to be zero terminated, it's not just a C quirk anymore, but burned forever into operating system ABIs too. A programming language which is supposed to interact with those APIs directly really shouldn't make this harder than it needs to be, and Zig's sentinel-terminated arrays are a pretty clever solution to the problem (even though they still need a temporary allocation to convert a regular slice to a zero-terminated slice for "dynamically built strings", but one can get surprisingly far with just string literals).
- 3836293648 4y agoAnd Rust has this for when you really hate yourself enough to use it. CString and CStr
- tialaramex 4y ago> pretty much all operating systems and fundamental C libraries expect strings to be zero terminated C libraries are going to mostly be like that because it's how C works. If that's our high bar we're never getting anywhere. Operating systems don't use many strings -- strings are awful because they're variable size and need parsing. Filenames are the most obvious place the kernel needs strings, and here the 0 terminating string is pretty horrible actually, the kernel can't assume the sentinel is present as that's obviously a massive security hole, so we end up not benefiting from the use of the sentinel, it's there because of C compatibility, as that wanes in significance there's no reason it needs to remain. On most operating systems the kernel system call ABI is not stable, which means you aren't supposed to rely on this stuff anyway, and once you're not talking directly to the kernel ABI you're free to choose abstractions which better suit both sides.