if (comptime builtin.mode == .Debug or builtin.mode == .ReleaseSafe) {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer std.debug.assert(gpa.deinit() == .ok);
const alloca = gpa.allocator();
} else {
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit();
const alloca = arena.allocator();
}
and then later I want to use alloca for ArrayLists, etc. Obviously this doesn’t work for a few reasons, mostly related to scoping, I think? const alloca is reported as an unused local constant in both branches of the if, and alloca is reported as undeclared at all use sites. All I want is for conditionally including the blocks of code in the comptime if… Any ideas on how to go about this? I looked around at similar topics and couldn’t find anything close enough to spark enlightenment, but maybe I’m missing something… Thanks!
That indeed does do the job; thanks! It does, however require splitting the comptime test in two. In this instance, that’s no problem at all, and I’ll implement something like this and move on with my day. However, in general is there some way to conditionally dump a block of code into a scope? If not, I guess that’s a restriction of comptime that I can work around (there was a blog post by Mitchell Hashimoto that seems relevant here) but it sure would be nice sometimes…
Those are nice wrappers, and I may use one or the other if I find I need this sort of thing a lot. In particular it does clean up my main a bit. However, in your first wrapper you now have six(!) instances of if (safe) and I really am wondering if it could just be one.
So I think in Zig you can use one if to switch between two different implementations of a type or namespace which both have the same methods or declarations, basically using static duck typing.
With the example you provided the main issue is that the allocator implementation needs to be placed in memory that isn’t temporary, I don’t think there is any way to use a single block for that.
Also I don’t know how that would work with newly introduced identifiers, I think that would be somewhat similar to the old implementation of usingnamespace where the introduced declarations where accessible locally and that was removed so that it is clearer where identifiers are introduced.
In ReleaseFast and ReleaseSmall modes, calls to this function are optimized away, and in fact the optimizer is able to use the assertion in its heuristics.
I don’t understand why you avoid the assert in ReleaseSafe, when you execute asserts (which you should because it is a safe mode), the manual test for the build mode is unnecessary, because it is already part of what assert does.
Also assert only takes one parameter, what is going on here?
the point is that the call to createTheValue() is not free. in my particular example it calls into a C library. it’s not particularly expensive either, i’ll own, but no point in even making the call if i don’t otherwise need the value