https://zig.news/sobeston/using-zig-and-translate-c-to-understand-weird-c-code-4f8 Skip to content [ ] Log in Create account Zig NEWS Zig NEWS is a community of amazing programmers Take off every Zig! Create new account Log in Zig NEWS * Home * Sign In/Up * FAQs Other * ziglang.org * ziglearn.org * zigmonthly.org * zigforum.org * zigbin.io * zig.run * zig.show loading... Copy Post URL Copied to Clipboard Share to Twitter Share to LinkedIn Share to Reddit Share to Hacker News Share to Facebook Share Post via... Report Abuse Cover image for Using Zig and Translate-C to understand weird C code Using Zig and Translate-C to understand weird C code [cG5n] Sobeston Sobeston [cG5n] Sobeston Follow * Joined Aug 8, 2021 Oct 9 2 min read void f(int *a) {
void *p = &a;
***(int *(*)[])p = 1;
} @rep_stosq_void on Twitter posted this strange sample of C code, and I wanted to show my process of understanding this contrived C code. https://twitter.com/rep_stosq_void/status/1446504706319294475 After running zig translate-c x.c > x.zig, I got the following output: pub export fn f(arg_a: [*c]c_int) void { var a = arg_a; var p: ?*c_void = @ptrCast(?*c_void, &a); @ptrCast( [*c][*c]c_int, @alignCast(@import("std").meta.alignment([*c]c_int), &@ptrCast( [*c][*c][*c]c_int, @alignCast(@import("std").meta.alignment([*c][*c]c_int), p), ).*), ).*.* = 1; } From here I removed the unnecessary calls to std.meta.alignment by adding alignment data to p. I also converted [*c]T pointers to [*]T and *T, depending on my assumptions of how the code works. I also removed the optional from p, and stripped away arg_a. Now we've got something a bit more faithful to the original. fn f(a: *c_int) void { const p = @ptrCast(*align(@alignOf(usize)) const c_void, &a); @ptrCast( *const [*]c_int, &@ptrCast(*const *[*]c_int, p).*, ).*.* = 1; } We can now transform &@ptrCast(*const *[*]c_int, p).* into @ptrCast (*const *[*]c_int, p), as &x.* is equivalent to x. fn g(a: *c_int) void { const p = @ptrCast(*align(@alignOf(usize)) const c_void, &a); @ptrCast( *const [*]c_int, @ptrCast(*const *[*]c_int, p), ).*.* = 1; } As we can see p is a pointer to the argument a, we can change its ptrCast to the more appropriate type *const *i32. The const is needed as arguments are immutable. fn h(a: *c_int) void { const p = @ptrCast(*const *i32, &a); @ptrCast( *const [*]c_int, @ptrCast(*const *[*]c_int, p), ).*.* = 1; } After substituting in p. fn i(a: *c_int) void { @ptrCast( *const [*]c_int, @ptrCast( *const *[*]c_int, @ptrCast(*const *i32, &a), ), ).*.* = 1; } There's some many-pointers ([*]T) here, which we should replace with single pointers (*T). This is because I can tell that there aren't really any arrays at play here. fn j(a: *c_int) void { @ptrCast( *const *c_int, @ptrCast( *const **c_int, @ptrCast(*const *i32, &a), ), ).*.* = 1; } Here we can remove the unnecessary ptrCast around &a, as &a is already of type *const *i32. fn k(a: *c_int) void { @ptrCast( *const *c_int, @ptrCast( *const **c_int, &a, ), ).*.* = 1; } Here we can see a ptrCast from *const *i32 to *const **c_int, back to *const *c_int. Let's remove that. fn l(a: *c_int) void { (&a).*.* = 1; } Finally, we can transform (&x).* into x. fn m(a: *c_int) void { a.* = 1; } Perhaps the answer is disappointing. Discussion (3) Subscribe pic [ ] [ ] Upload image [Upload] [ ] Templates Personal Moderator loading Create template Templates let you quickly answer FAQs or store snippets for re-use. Submit Preview Dismiss kristoff profile image Loris Cro Loris Cro [bmc] Loris Cro I swear I didn't put that bug there Follow * Work Creator and Host at Zig SHOWTIME * Joined Jul 25, 2021 * Oct 9 * Copy link * * Hide * * * Perhaps the answer is disappointing Kinda, yeah, lol. 3 likes Reply vadavaski profile image vadavaskki vadavaskki [LnBuZw] vadavaskki Follow * Joined Nov 3, 2021 * Nov 3 * Copy link * * Hide * * * You translate 1 line of C mess to 7 lines of Zig mess which are then manually simplified through transforms. Why not just apply transforms to the original C code? 1 like Reply sobeston profile image Sobeston Sobeston [cG5n] Sobeston Follow * Joined Aug 8, 2021 * Nov 3 * Copy link * * Hide * * * I answered this here news.ycombinator.com/item?id=29099284 1 like Reply Code of Conduct * Report abuse Read next klltkr profile image WebAssembly interpreter optimisation: part 1 Malcolm Still - Feb 27 klltkr profile image WebAssembly interpreter optimisation: part 3 Malcolm Still - Oct 8 klltkr profile image WebAssembly interpreter optimisation: part 2 Malcolm Still - Mar 7 andres profile image Crafting an Interpreter in Zig - part 4 Andres - Sep 27 [cG5n] Sobeston Follow * Joined Aug 8, 2021 More from Sobeston A Guessing Game #learn #beginners Fahrenheit To Celsius #learn #beginners Fizz Buzz #learn #beginners Zig NEWS - Read the latest happenings in the global Zig community. Built on Forem -- the open source software that powers DEV and other inclusive communities. Made with love and Ruby on Rails. Zig NEWS (c) 2021. Zig NEWS Take off every Zig! Log in Create new account We strive for transparency and don't collect excess data.