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.