Skip to content

Commit

Permalink
packed struct (#181)
Browse files Browse the repository at this point in the history
* code recognize

* nothing

* remove useless file

* source file

* 增加 packed 重新排序说明

* 格式化
  • Loading branch information
jinzhongjia authored Sep 4, 2024
1 parent 61861e7 commit 6e1a764
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 26 deletions.
Binary file modified bun.lockb
Binary file not shown.
51 changes: 35 additions & 16 deletions course/basic/advanced_type/struct.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 基于一套规则来进行命名:
Expand Down
10 changes: 0 additions & 10 deletions course/code/12/build_system/test/src/root.zig

This file was deleted.

37 changes: 37 additions & 0 deletions course/code/12/struct.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
37 changes: 37 additions & 0 deletions course/code/14/struct.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

0 comments on commit 6e1a764

Please sign in to comment.