This fixes it:
const std = @import("std");
const print = std.log.info;
const CA = struct {
s: *S,
};
const CB = struct {
s: *S,
s2: *S2,
};
const S = struct {
x: u32 = 10,
};
const S2 = struct {
y: u32 = 5,
};
fn create(T: type, name: []const u8, key: anytype) *T {
return &struct {
var o = blk: {
std.mem.doNotOptimizeAway(key);
std.mem.doNotOptimizeAway(name);
break :blk std.mem.zeroInit(T, .{});
};
}.o;
}
fn initC(CT: type) CT {
comptime {
var new_c: CT = undefined;
const cti = @typeInfo(CT);
for (cti.Struct.fields, 0..) |fld, i| {
const fti = @typeInfo(fld.type);
const FT = fti.Pointer.child;
const fval = create(FT, @typeName(CT), i);
@field(new_c, fld.name) = fval;
}
const res = new_c;
return res;
}
}
const ca = initC(CA);
const cb = initC(CB);
pub fn main() void {
ca.s.x = 20;
cb.s.x = 25;
print("ca.s.x = {d}", .{ca.s.x});
print("cb.s.x = {d}", .{cb.s.x});
print("cb.2.y = {d}", .{cb.s2.y});
}
Unfortunately, I don’t have a lot of time to automate this process. The thing is, @Sze is right that this process is starting to look brittle to me. At this level, I would start using file generation instead of comptime.