mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 14:23:09 +00:00
Processed review comments. Updated documentation, used the typinfo for field access, generate compile error on allowzero and set C poitners to null
This commit is contained in:
parent
195195d238
commit
f7aa4f5280
@ -276,8 +276,12 @@ pub fn set(comptime T: type, dest: []T, value: T) void {
|
||||
d.* = value;
|
||||
}
|
||||
|
||||
/// Generally, Zig users are encouraged to explicitly initialize all fields of a struct explicitly rather than using this function.
|
||||
/// However, it is recognized that there are sometimes use cases for initializing all fields to a "zero" value. For example, when
|
||||
/// interfacing with a C API where this practice is more common and relied upon. If you are performing code review and see this
|
||||
/// function used, examine closely - it may be a code smell.
|
||||
/// Zero initializes the type.
|
||||
/// This can be used to zero initialize a C-struct.
|
||||
/// This can be used to zero initialize a any type for which it makes sense. Structs will be initialized recursively.
|
||||
pub fn zeroes(comptime T: type) T {
|
||||
switch (@typeInfo(T)) {
|
||||
.ComptimeInt, .Int, .ComptimeFloat, .Float => {
|
||||
@ -295,7 +299,7 @@ pub fn zeroes(comptime T: type) T {
|
||||
.Optional, .Null => {
|
||||
return null;
|
||||
},
|
||||
.Struct => {
|
||||
.Struct => |struct_info| {
|
||||
if (@sizeOf(T) == 0) return T{};
|
||||
if (comptime meta.containerLayout(T) == .Extern) {
|
||||
var item: T = undefined;
|
||||
@ -303,26 +307,24 @@ pub fn zeroes(comptime T: type) T {
|
||||
return item;
|
||||
} else {
|
||||
var structure: T = undefined;
|
||||
comptime var field_i = 0;
|
||||
inline while (field_i < @memberCount(T)) : (field_i += 1) {
|
||||
@field(structure, @memberName(T, field_i)) = zeroes(@TypeOf(@field(structure, @memberName(T, field_i))));
|
||||
inline for (struct_info.fields) |field| {
|
||||
@field(structure, field.name) = zeroes(@TypeOf(@field(structure, field.name)));
|
||||
}
|
||||
return structure;
|
||||
}
|
||||
},
|
||||
.Pointer => |ptr_info| {
|
||||
if (ptr_info.is_allowzero) {
|
||||
return null;
|
||||
} else {
|
||||
switch (ptr_info.size) {
|
||||
.Slice => {
|
||||
return &[_]ptr_info.child{};
|
||||
},
|
||||
.One, .Many, .C => {
|
||||
.C => {
|
||||
return null;
|
||||
},
|
||||
.One, .Many => {
|
||||
@compileError("Can't set a non nullable pointer to zero.");
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
.Array => |info| {
|
||||
var array: T = undefined;
|
||||
@ -372,6 +374,7 @@ test "mem.zeroes" {
|
||||
|
||||
const Pointers = struct {
|
||||
optional: ?*u8,
|
||||
c_pointer: [*c]u8,
|
||||
slice: []u8,
|
||||
};
|
||||
pointers: Pointers,
|
||||
@ -397,6 +400,7 @@ test "mem.zeroes" {
|
||||
testing.expectEqual(@as(f32, 0), b.integral_types.float_32);
|
||||
testing.expectEqual(@as(f64, 0), b.integral_types.float_64);
|
||||
testing.expectEqual(@as(?*u8, null), b.pointers.optional);
|
||||
testing.expectEqual(@as([*c]u8, null), b.pointers.c_pointer);
|
||||
testing.expectEqual(@as([]u8, &[_]u8{}), b.pointers.slice);
|
||||
for (b.array) |e| {
|
||||
testing.expectEqual(@as(u32, 0), e);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user