-
-
Notifications
You must be signed in to change notification settings - Fork 2.8k
@typeInfo
strings cannot be null terminated.
#9182
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
The code that broke with the local changes I had for amending So, another option: introduce a comptime allocator to unbreak code that follows a similar pattern even if But it'd still make its use a bit more awkward, potentially requiring the user to allocate/deallocate memory whereas now no such dance is required. |
Actually, this can be done: const std = @import("std");
const testing = std.testing;
const text =
\\f1
\\f2
\\f3
;
test "issue 6456" {
comptime var gen_fields: []const [:0]const u8 = &[_][:0]const u8{};
comptime {
var it = std.mem.tokenize(text, "\n");
while (it.next()) |name| {
const name_z = name ++ "\x00";
const name_z_slice: [:0]const u8 = name_z[0..name.len :0];
gen_fields = gen_fields ++ [_][:0]const u8{name_z_slice};
}
}
try testing.expectEqualStrings("f1", gen_fields[0]);
try testing.expectEqualStrings("f2", gen_fields[1]);
try testing.expectEqualStrings("f3", gen_fields[2]);
try testing.expectEqual(@as(u8, 0), gen_fields[0][gen_fields[0].len]);
try testing.expectEqual(@as(u8, 0), gen_fields[1][gen_fields[1].len]);
try testing.expectEqual(@as(u8, 0), gen_fields[2][gen_fields[2].len]);
} Edit: here's a function to do this that would be suitable for fn addZ(comptime T: type, comptime s: []const T) [:0]T {
var arr: [s.len + 1]T = undefined;
std.mem.copy(T, &arr, s);
arr[s.len] = 0;
return arr[0..s.len :0];
} |
Hmm, I suppose you're right. That's definitely more awkward code though, but manageable. Especially if something like |
A very easy way to convert a comptime-known const std = @import("std");
const testing = std.testing;
const text =
\\f1
\\f2
\\f3
;
test "issue 6456" {
comptime var gen_fields: []const [:0]const u8 = &[_][:0]const u8{};
comptime {
var it = std.mem.tokenizeScalar(u8, text, '\n');
while (it.next()) |name| {
gen_fields = gen_fields ++ .{name ++ ""};
}
}
try testing.expectEqualStrings("f1", gen_fields[0]);
try testing.expectEqualStrings("f2", gen_fields[1]);
try testing.expectEqualStrings("f3", gen_fields[2]);
try testing.expectEqual(@as(u8, 0), gen_fields[0][gen_fields[0].len]);
try testing.expectEqual(@as(u8, 0), gen_fields[1][gen_fields[1].len]);
try testing.expectEqual(@as(u8, 0), gen_fields[2][gen_fields[2].len]);
} If we can accept the slight awkwardness of it, it might be an acceptable tradeoff to break code that reifies types from strings tokenized at comptime (suggesting |
Taken from #8636.
I see three ways to fix this.
@typeInfo
and@Type
, which would break even more code.[]T -> [:t]T
and*[N]T -> *[N:t]T
when the value is comptime known.The last option would likely solve some other awkwardness about dealing with sentinel terminated values but includes a lot of implicitness.
The text was updated successfully, but these errors were encountered: