I initialize a struct field with:
private_keydata: std.ArrayList([] u8) = .empty,
I do nothing with this field in between and test:
assert(self.private_keydata.items.len == 0);
The assertion fails. What exactly does = .empty do?
I initialize a struct field with:
private_keydata: std.ArrayList([] u8) = .empty,
I do nothing with this field in between and test:
assert(self.private_keydata.items.len == 0);
The assertion fails. What exactly does = .empty do?
It’s a declaration literal. You can see exactly what it does by looking at the pub const empty declaration in ArrayList in the standard library, which ships as source code with Zig.
Is there a chance to read into what .empty is meant to do (like documentation or specification), or is there only an implementation, and that’s what the current version of it does?
These are equivalent:
var private_keydata = std.ArrayList([] u8).empty;
var private_keydata: std.ArrayList([] u8) = .empty;
The second is preferred.
Yes, there’s a doc comment that’s almost redundant:
/// An ArrayList containing no elements.
pub const empty: Self = .{
.items = &.{},
.capacity = 0,
};
How are you initializing / creating the struct? By the sounds of it you’re setting something to undefined, or not initializing something you created on the heap.
This should pass:
var array: std.ArrayList([]u8) = .empty;
std.debug.assert(array.items.len == 0);
My guess would be that you didn’t actually initialize self. (But I can’t know for sure without seeing more code)
Note that Allocation is not Initialization.
You are right. I did set the struct = undefined;which seems to suppress compile time initialization (which I was not aware of). Thank you.
“compile-time initialization” is a little different from what is happening with the line that you quoted. i’d prefer “default value”. if every field of a struct type T has a default value, then
var instance: T = .{};
is legal and will produce something with every field given that default value. additionally, if you instead fill in all fields without a default value, the fields you skipped will receive their default value. in all cases, the write to that memory is (of course) happening at run time, but the pattern of bits for the fields with default values is known at compile time.
setting var instance: T = undefined; is similar in that regard: at runtime it gives you enough properly aligned memory to store a T, but where it is different is that it is “illegal behavior” to rely on the value of that block of memory—as you do when you use the assert. the current behavior (do not rely on this) in Debug mode, for instance, is that the bit pattern 0xaa == 0b10101010 is written to everything within T. in particular, the len field receives a value of 0xaa repeated to fill a usize—that’s a pretty big nonzero number. (my understanding is that the purpose of this is to help with debugging by using a distinctive bit pattern)
If you’re going to accept an answer here it should be @Sze’s, it’s less blunt and rude than mine and gets to the point sooner.
When I ask a question and someone invests his time and thought to help me out I would never consider this person being rude, but right the opposite.
Thanks to everyone here, who supports me by doing so!