authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-06 13:06:28-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-06 13:06:28-07:00
logde1fb199091ef1b3ae53d4de0fc30fa958131c96
tree17eb6555c32661abf27253379afb5396f72c5084
parentddcb7b1c11f88c4ae150b36807033060a469dcb5
parent679ad36fa069a723aa9094afbd09d1b460232dda
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #20951 from ehaas/c-size-and-align-check

tools: Add tool for checking size and alignment of C types

2 files changed, 62 insertions(+), 0 deletions(-)

test/standalone/build.zig+1
...@@ -34,6 +34,7 @@ pub fn build(b: *std.Build) void {...@@ -34,6 +34,7 @@ pub fn build(b: *std.Build) void {
34 "../../tools/gen_outline_atomics.zig",34 "../../tools/gen_outline_atomics.zig",
35 "../../tools/gen_spirv_spec.zig",35 "../../tools/gen_spirv_spec.zig",
36 "../../tools/gen_stubs.zig",36 "../../tools/gen_stubs.zig",
37 "../../tools/generate_c_size_and_align_checks.zig",
37 "../../tools/generate_linux_syscalls.zig",38 "../../tools/generate_linux_syscalls.zig",
38 "../../tools/process_headers.zig",39 "../../tools/process_headers.zig",
39 "../../tools/update-linux-headers.zig",40 "../../tools/update-linux-headers.zig",
tools/generate_c_size_and_align_checks.zig created+61
...@@ -0,0 +1,61 @@
1//! Usage: zig run tools/generate_c_size_and_align_checks.zig -- [target_triple]
2//! e.g. zig run tools/generate_c_size_and_align_checks.zig -- x86_64-linux-gnu
3//!
4//! Prints _Static_asserts for the size and alignment of all the basic built-in C
5//! types. The output can be run through a compiler for the specified target to
6//! verify that Zig's values are the same as those used by a C compiler for the
7//! target.
8
9const std = @import("std");
10
11fn c_name(ty: std.Target.CType) []const u8 {
12 return switch (ty) {
13 .char => "char",
14 .short => "short",
15 .ushort => "unsigned short",
16 .int => "int",
17 .uint => "unsigned int",
18 .long => "long",
19 .ulong => "unsigned long",
20 .longlong => "long long",
21 .ulonglong => "unsigned long long",
22 .float => "float",
23 .double => "double",
24 .longdouble => "long double",
25 };
26}
27
28var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
29
30pub fn main() !void {
31 const gpa = general_purpose_allocator.allocator();
32 defer std.debug.assert(general_purpose_allocator.deinit() == .ok);
33
34 const args = try std.process.argsAlloc(gpa);
35 defer std.process.argsFree(gpa, args);
36
37 if (args.len != 2) {
38 std.debug.print("Usage: {s} [target_triple]\n", .{args[0]});
39 std.process.exit(1);
40 }
41
42 const query = try std.Target.Query.parse(.{ .arch_os_abi = args[1] });
43 const target = try std.zig.system.resolveTargetQuery(query);
44
45 const stdout = std.io.getStdOut().writer();
46 inline for (@typeInfo(std.Target.CType).Enum.fields) |field| {
47 const c_type: std.Target.CType = @enumFromInt(field.value);
48 try stdout.print("_Static_assert(sizeof({0s}) == {1d}, \"sizeof({0s}) == {1d}\");\n", .{
49 c_name(c_type),
50 target.c_type_byte_size(c_type),
51 });
52 try stdout.print("_Static_assert(_Alignof({0s}) == {1d}, \"_Alignof({0s}) == {1d}\");\n\n", .{
53 c_name(c_type),
54 target.c_type_alignment(c_type),
55 });
56 try stdout.print("_Static_assert(__alignof({0s}) == {1d}, \"__alignof({0s}) == {1d}\");\n\n", .{
57 c_name(c_type),
58 target.c_type_preferred_alignment(c_type),
59 });
60 }
61}