11 ms·
Wouldn’t this add at least UINT16_MAX*sizeof(intptr_t) bytes into the executable per enum?
by eska 2y ago
Wouldn’t this add at least UINT16_MAX*sizeof(intptr_t) bytes into the executable per enum?
- flohofwoe 2y agoI think the executable will essentially contain a lookup table with 2^16 slots and the string data for each macro name matching WM_* in Windows.h. But it's hard to come up with a better solution since the actually required names are unpredictable at compile time. The size of the lookup table could be reduced though if the WM_* values occupy a much smaller range.
- Cloudef 2y agoIt adds 65536 pointers to the binary. Alternative would be to use a hash map. I think if they made function that used inline for instead it would optimize to a switch. No need for a LUT. fn stringFromMsg(umsg: c_int) [:0]const u8 { @setEvalBranchQuota(1000000); inline for (@typeInfo(win32).Struct.decls) |field| { if (field.name.len >= 3 and std.mem.eql(u8, field.name[0..3], "WM_")) { if (umsg == @field(win32, field.name)) { return field.name; } } } unreachable; // umsg is not valid, programming mistake } godbolt: https://zig.godbolt.org/z/7b73aoosf https://zig.godbolt.org/z/7b73aoosf In zig-budoux, I also do comptime reflection on cImport struct to assert compile time that we won't produce broken runtime code https://github.com/Cloudef/zig-budoux/blob/master/src/c.zig#L8-L18 https://github.com/Cloudef/zig-budoux/blob/master/src/c.zig#...
- flohofwoe 2y ago> ...instead it would optimize to a switch. No need for a LUT. IME there's is no difference in (optimized) code generation between an if-else chain, a switch or (like in your example) an unrolled for-loop with an if inside. All those high level constructs will be optimized into a single lookup table, or a combination of multiple lookup tables and binary search to select between those. Only if there are absolutely no consecutive ranges in the switch-set, a binary search without jump tables will be used.
- Cloudef 2y agoNote that you can't use normal for here as you are accessing comptime known variables. Inline for will unroll the loop so that comptime constants get resolved for testing against runtime variables and then the optimizer picks out the best code (often jump tables / switch) to generate. You are right though.