I don’t have a specific problem to solve or issue other than trying to understand how comptime works.
In StaticStringMapWithEql.initComptime() function, my understanding is that the sorting and bucketing for the map is done at compile time. The bits that make up the StringMap object are, for lack of a better term, copied into the runtime.
When I look at the implementation of initComptime(), the comptime block was storing stack allocated array pointers in the returned object. Here is a snippet:
In non-comptime code, final_len_indexes would be stack allocated and putting that pointer in the returned self object would be bad. Yet, the StaticStringMaps initialized with initComptime seem to work fine in my code (in comptime blocks and non-comptime blocks).
Does a comptime block have its own concept of a stack? What is “&final_len_indexes” pointing to? When the self object is returned, it contains a pointer to “final_len_indexes” via “self.len_indexes”. I don’t understand how self.len_indexes ultimately contains a valid pointer.
As far as I understand, in comptime, all values are allocated in an arena (on a per-block/per-decl basis) and not on a stack so there’s no issues around dangling pointers.
I think I got this from @mlugg, who I believe would be the ideal person to answer this
The comptime generated array, which is stored in your programs static data segment. self.len_indexes is a runtime value of type [*]const u32, so it stores a pointer to the static memory but cannot write to it.
I believe it’s arena allocation, not reference counting, and I’m not sure where you’re getting the dynamic typing idea from, I’m pretty sure all normal static type rules apply.
I do find it useful to think of comptime like a ‘zig interpreter’ though.
I don’t have information about how it is implemented. It is rather a deduction. Because what is possible in comptime, to be statically typed, would need a dependent type theory implementation (Dependent type - Wikipedia), and I know for sure Zig doesn’t have it. Now knowing that some values have to by dynamically typed, there are no reason to think some are and other don’t. Sure, type indication will force type, but its different from static typing.
Also, for reference counting, it is also an intuition, as from my experience, any value can escape its defining scope, there won’t be an undefined behavior. I just don’t see any other mechanism than reference counting that can do so (and garbage collection). Even an arena allocator has a scope.
Ah, I see what you mean. Yeah, I imagine the compiler needs some sort of dynamic value type, but as far as the user is concerned there’s no difference.
Ah, but of course I misread it. This is talking about temporary state the compiler has when processing these comptime values. The values themselves are stored in an InternPool, which in theory would be garbage collected:
It makes sense that the data would be in the ro section at runtime. I suppose it can’t really live anywhere else.
I am still a little unsure how final_len_indexes gets into the ro section. Is it because it is declared const or the & operator is used in the assignment?