diff --git a/bun.lockb b/bun.lockb index d680f7fc..ac1d6491 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/course/basic/advanced_type/struct.md b/course/basic/advanced_type/struct.md index bfdb556c..f6ffd2ef 100644 --- a/course/basic/advanced_type/struct.md +++ b/course/basic/advanced_type/struct.md @@ -197,24 +197,43 @@ zig 在使用结构体的时候还支持省略结构体类型,只要能让 zig 3. 还可以对 `packed` 的结构体的指针设置内存对齐来访问对应的字段: -> 这里说明可能有些不清楚,请见谅! - -```zig -const std = @import("std"); -const expect = std.testing.expect; - -const S = packed struct { - a: u32, - b: u32, -}; -test "overaligned pointer to packed struct" { - var foo: S align(4) = .{ .a = 1, .b = 2 }; - const ptr: *align(4) S = &foo; - const ptr_to_b: *u32 = &ptr.b; - try expect(ptr_to_b.* == 2); -} +:::details 示例 + +<<<@/code/release/struct.zig#aligned_struct + +::: + +4. 默认情况下 zig 还会对字段进行重新排序,但是在 packed 下并不会重新排序。 + +:::details 示例 + +<<<@/code/release/struct.zig#reorder_struct + +输出为: + +```sh +16 +12 +0 +4 ``` +在 64 位系统上,Foo 的内存布局是: + +```sh +| 4(i32) | 8(pointer) | 4(padding) | +``` + +如果去掉 packed,则是 + +```sh +| 8(pointer | 4(int32) | 4(padding) | +``` + +可以看到, Zig 会对字段进行重新排序。 + +::: + ### 命名规则 由于在 zig 中很多结构是匿名的(例如可以把一个源文件看作是一个匿名的结构体),所以 zig 基于一套规则来进行命名: diff --git a/course/code/12/build_system/test/src/root.zig b/course/code/12/build_system/test/src/root.zig deleted file mode 100644 index ecfeade1..00000000 --- a/course/code/12/build_system/test/src/root.zig +++ /dev/null @@ -1,10 +0,0 @@ -const std = @import("std"); -const testing = std.testing; - -export fn add(a: i32, b: i32) i32 { - return a + b; -} - -test "basic add functionality" { - try testing.expect(add(3, 7) == 10); -} diff --git a/course/code/12/struct.zig b/course/code/12/struct.zig index cdab3de3..ce61cd1e 100644 --- a/course/code/12/struct.zig +++ b/course/code/12/struct.zig @@ -363,3 +363,40 @@ const PackedCast = struct { } // #endregion packed_cast }; + +const aligned_struct = struct { + // #region aligned_struct + const std = @import("std"); + const expect = std.testing.expect; + + const S = packed struct { + a: u32, + b: u32, + }; + test "overaligned pointer to packed struct" { + var foo: S align(4) = .{ .a = 1, .b = 2 }; + const ptr: *align(4) S = &foo; + const ptr_to_b: *u32 = &ptr.b; + try expect(ptr_to_b.* == 2); + } + // #endregion aligned_struct +}; + +const reorder_struct = struct { + // #region reorder_struct + const std = @import("std"); + + const Foo = packed struct { + x: i32, + y: [*]i32, // 一个多项指针 + }; + + pub fn main() !void { + std.debug.print("{any}\n", .{@sizeOf(Foo)}); + std.debug.print("{any}\n", .{@bitSizeOf(Foo) / 8}); + + std.debug.print("{any}\n", .{@bitOffsetOf(Foo, "x") / 8}); + std.debug.print("{any}\n", .{@bitOffsetOf(Foo, "y") / 8}); + } + // #endregion reorder_struct +}; diff --git a/course/code/14/struct.zig b/course/code/14/struct.zig index cdab3de3..ce61cd1e 100644 --- a/course/code/14/struct.zig +++ b/course/code/14/struct.zig @@ -363,3 +363,40 @@ const PackedCast = struct { } // #endregion packed_cast }; + +const aligned_struct = struct { + // #region aligned_struct + const std = @import("std"); + const expect = std.testing.expect; + + const S = packed struct { + a: u32, + b: u32, + }; + test "overaligned pointer to packed struct" { + var foo: S align(4) = .{ .a = 1, .b = 2 }; + const ptr: *align(4) S = &foo; + const ptr_to_b: *u32 = &ptr.b; + try expect(ptr_to_b.* == 2); + } + // #endregion aligned_struct +}; + +const reorder_struct = struct { + // #region reorder_struct + const std = @import("std"); + + const Foo = packed struct { + x: i32, + y: [*]i32, // 一个多项指针 + }; + + pub fn main() !void { + std.debug.print("{any}\n", .{@sizeOf(Foo)}); + std.debug.print("{any}\n", .{@bitSizeOf(Foo) / 8}); + + std.debug.print("{any}\n", .{@bitOffsetOf(Foo, "x") / 8}); + std.debug.print("{any}\n", .{@bitOffsetOf(Foo, "y") / 8}); + } + // #endregion reorder_struct +};