Hi everyone,
I have a question about “string” comparison at compile time. I want to know the value of a specific structure’s field at compile time. For now, what I came up with is iterating over all the structure’s fields and stop when I find the one I want, something like:
const std = @import("std");
pub const Foo = struct { a: i64, bar: f64 };
pub fn main() void {
const infos = @typeInfo(Foo);
inline for (infos.@"struct".fields) |f| {
if (std.mem.eql(u8, "a", f.name)) {
@compileLog("Here");
if ("a".len == f.name.len) {
@compileLog("Same length");
}
}
}
}
The call to eql
evaluates as true
for every field of the structure, resulting in printing twice "Here"
. When I look at std.mem.eql
source code, I see that at compile time (after the if
having for first condition !@inComptime()
), the first test is comparing the length of the two slices.
I don’t know how but it seems to be true for each field’s name.
Source code of std.mem.eql
:
pub fn eql(comptime T: type, a: []const T, b: []const T) bool {
if (!@inComptime() and @sizeOf(T) != 0 and std.meta.hasUniqueRepresentation(T) and
eqlBytes_allowed)
{
return eqlBytes(sliceAsBytes(a), sliceAsBytes(b));
}
if (a.len != b.len) return false;
...
}
When I put the same length test in my code with the compile log "Same length"
, I see it printed only once in the console.
What I am missing here?
Output:
test_reflection.zig:10:13: error: found compile log statement
@compileLog("Here");
^~~~~~~~~~~~~~~~~~~
Compile Log Output:
@as(*const [4:0]u8, "Here")
@as(*const [11:0]u8, "Same length")
@as(*const [4:0]u8, "Here")
Thanks!