That was a nice, clear explanation that even I could understand. One thing I wasn't sure about, though. var arr = [_]u32{ 1, 2, 3, 4, 5, 6 }; // 1, 2, 3, 4, 5, 6 const slice1 = arr[1..5]; // 2, 3, 4, 5 const slice2 = slice1[1..3]; If I were to use indices out of range, presumably that would that give me a compile time error? Could I use variables as the indices and, if so, could I get a seg fault at runtime or are th…
Problems of C, and how Zig addresses them
21–30 of 290 posts
Re: Problems of C, and how Zig addresses them
#22Naturally it doesn't show how it tackles use-after-free cases.
Another thing that caught me by surprise is passing arrays as references. Ages ago we used to pass arrays (`int arr[100]`) as pointers (`int*`). I'm sure C still supports this?
Re: Problems of C, and how Zig addresses them
#23Naturally it doesn't show how it tackles use-after-free cases.
Yup. It offers tests as a solution, which is nice I guess, but kind if reminds me of Valgrind. Another thing that caught me by surprise is passing arrays as references. Ages ago we used to pass arrays (`int arr[100]`) as pointers (`int*`). I'm sure C still supports this?
Re: Problems of C, and how Zig addresses them
#24Earlier quoted context omitted.
Would you mind elaborating on the complications you ran into? I ask because I think you used std.HashMap instead of std.AutoHashMap, the latter of which automatically chooses a hash function based on the types provided.
It was a little over a week ago now so my memory is a bit hazy, but I'll try to the best of my knowledge. Without getting into the weeds of why (happy to do so, just want to keep this readable), basically I needed to define and populate a hashmap in a new script and then import it into my main script, which to my mind left me with two options: * Define and initialise it at the same time (my preferred method) as a con…
Re: Problems of C, and how Zig addresses them
#25That was a nice, clear explanation that even I could understand. One thing I wasn't sure about, though. var arr = [_]u32{ 1, 2, 3, 4, 5, 6 }; // 1, 2, 3, 4, 5, 6 const slice1 = arr[1..5]; // 2, 3, 4, 5 const slice2 = slice1[1..3]; If I were to use indices out of range, presumably that would that give me a compile time error? Could I use variables as the indices and, if so, could I get a seg fault at runtime or are th…
Zig has bounds checking built-in. You can decide to remove it if you compile for ReleaseSafe instead of ReleaseFast, but it's always in debug builds.
Re: Problems of C, and how Zig addresses them
#26Re: Problems of C, and how Zig addresses them
#27Re: Problems of C, and how Zig addresses them
#28I'm no expert on either languages, but I tried Zig for the first time properly the other day. I really liked it up until I hit hashmaps. One thing that I think goes under-appreciated about C (and other languages with a similar paradigm) is thats its pretty upfront and clear about what it can and can't do out of the box. If you want hashmaps in C, you need to create your own implementation, otherwise think of a way ro…
Zig hashmaps _are_ quite a bit more cumbersome than, eg, in Rust --- you need to decided whether you want the allocator to be bundled with the hasmap, and its also up to the user of the hash map to provide equality and hash code (and, of course, there's manual defer instead of RAII).
However, this flexibility and verbosity comes with a super-power --- you can pass an allocator to a hash map at creation time, and then _not_ pass an allocator when you actually use the hash map. This is huge. This means that we get compile-time guarantee that we follow rule 3 of NASA's 10 rules
3. Do not use dynamic memory allocation after initialization.
And we _still_ can enjoy using a hashmap from the standard library! No other language I know has an equivalent tool.Re: Problems of C, and how Zig addresses them
#29Naturally it doesn't show how it tackles use-after-free cases.
Rather than offer drive-by criticism, perhaps you could illustrate 'the problem' you are suggesting is being hidden?
Re: Problems of C, and how Zig addresses them
#30That was a nice, clear explanation that even I could understand. One thing I wasn't sure about, though. var arr = [_]u32{ 1, 2, 3, 4, 5, 6 }; // 1, 2, 3, 4, 5, 6 const slice1 = arr[1..5]; // 2, 3, 4, 5 const slice2 = slice1[1..3]; If I were to use indices out of range, presumably that would that give me a compile time error? Could I use variables as the indices and, if so, could I get a seg fault at runtime or are th…
yup
$ zig test test.zig
test.zig:8:56: error: index 3 outside array of length 2
std.debug.print("\ncompile error: {d}\n", .{slice2[3]});
> Could I use variables as the indices and, if so, could I get a seg fault at runtime or are there some sort of guards on there?Bounds are checked by default:
$ zig test test.zig
test.zig:9:56: error: index 3 outside array of length 2
std.debug.print("\ncompile error: {d}\n", .{slice2[invalid_index]});
But you can disable them by building in `ReleaseFast` mode[1]Here's a test file you can use to play around with it if you like:
const std = @import("std");
test "bounds" {
var arr = [_]u32{ 1, 2, 3, 4, 5, 6 }; // 1, 2, 3, 4, 5, 6
const slice1 = arr[1..5]; // 2, 3, 4, 5
const slice2 = slice1[1..3]; // 3, 4
const invalid_index: usize = 3;
std.debug.print("\nslice2: {d} {d}\n", .{ slice2[0], slice2[1] });
std.debug.print("\ncompile error: {d}\n", .{slice2[invalid_index]});
try std.testing.expect(slice2.len == 2);
}
1: https://ziglang.org/documentation/master/#Build-Mode