Open utterances-bot opened 1 year ago
Great post Orhun. I was trying to figure out how to deal with this a few weeks ago. Quick question... keep in mind I'm still new to Zig... Is this line for the allocator missing a closing param?
var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
Thanks again for the post.
Thank you @digeratus!
Is this line for the allocator missing a closing param?
What exactly do you mean by "closing param"?
FWIW I took that example code from the Zig documentation.
Isn't it missing a ")" at the end before you finish the variable assignment?
std.heap.GeneralPurposeAllocator(.{}){}<isn't missing a parenthesis here>;
Disregard. I think I see my misunderstanding.
Folks, so what does the trailing {}
symbols mean there, right after the GeneralPurposeAllocator()
?
Good question. If we look at the signature of GeneralPurposeAllocator
:
fn GeneralPurposeAllocator(comptime config: Config) type
We can see that it returns a generic struct (type
). In that case, the curly braces after the function call mean that we can override the fields of that struct.
pub fn GeneralPurposeAllocator(comptime config: Config) type {
return struct {
backing_allocator: Allocator = std.heap.page_allocator,
buckets: [small_bucket_count]?*BucketHeader = [1]?*BucketHeader{null} ** small_bucket_count,
...
Like so:
var gpa = GeneralPurposeAllocator(.{}){ .backing_allocator = std.testing.allocator };
To be a little more precise, GeneralPurposeAllocator(…)
returns a new type — a struct-based one (as opposed to enum-based or whatever). You could decompose it like this:
// See https://github.com/ziglang/zig/blob/5d63d1115f0f18984ed7c517c2d85224aa4da444/lib/std/heap/general_purpose_allocator.zig#L115-L156 for what can go in this "Config" parameter.
// Note these configuration options are comptime values — they can influence the code generated for the GPA.
const MyGPAType = std.heap.GeneralPurposeAllocator(.{ .safety = false });
pub fn main() !void {
// Here we can configure a different set of properties, these changeable at runtime.
var gpa = MyGPAType{ .backing_allocator = std.testing.allocator };
defer _ = gpa.deinit();
const allocator = gpa.allocator();
// … etc.
}
So std.heap.GeneralPurposeAllocator(.{}){}
creates a new type (returned from the call to GeneralPurposeAllocator(…)
), then instantiates one copy of it (with {}
, accepting all default values for the struct type itself).
Folks, thank you both!
Orhun's Blog
FOSS • Linux • Programming
https://blog.orhun.dev/zig-bits-02/