aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvan Haas <evan@lagerdata.com>2024-08-05 12:54:56 -0700
committerEvan Haas <evan@lagerdata.com>2024-08-05 12:56:40 -0700
commit4bdf04654e3bd8ac09882cb49595f6797f2f5d09 (patch)
tree8c7ec69c6820197400ba83ac375524a1436df10e
parent724804a4e026eea8cd42804b44bb0449d4ab3f3c (diff)
downloadzig-4bdf04654e3bd8ac09882cb49595f6797f2f5d09.tar.gz
zig-4bdf04654e3bd8ac09882cb49595f6797f2f5d09.zip
tools: Add tool for checking size and alignment of C types
Prints _Static_asserts for the size and alignment of all the basic built-in C types. The output can be run through a compiler for the specified target to verify that Zig's values are the same as those used by a C compiler for the target.
-rw-r--r--tools/generate_c_size_and_align_checks.zig57
1 files changed, 57 insertions, 0 deletions
diff --git a/tools/generate_c_size_and_align_checks.zig b/tools/generate_c_size_and_align_checks.zig
new file mode 100644
index 0000000000..ed52da6286
--- /dev/null
+++ b/tools/generate_c_size_and_align_checks.zig
@@ -0,0 +1,57 @@
+//! Usage: zig run tools/generate_c_size_and_align_checks.zig -- [target_triple]
+//! e.g. zig run tools/generate_c_size_and_align_checks.zig -- x86_64-linux-gnu
+//!
+//! Prints _Static_asserts for the size and alignment of all the basic built-in C
+//! types. The output can be run through a compiler for the specified target to
+//! verify that Zig's values are the same as those used by a C compiler for the
+//! target.
+
+const std = @import("std");
+
+fn c_name(ty: std.Target.CType) []const u8 {
+ return switch (ty) {
+ .char => "char",
+ .short => "short",
+ .ushort => "unsigned short",
+ .int => "int",
+ .uint => "unsigned int",
+ .long => "long",
+ .ulong => "unsigned long",
+ .longlong => "long long",
+ .ulonglong => "unsigned long long",
+ .float => "float",
+ .double => "double",
+ .longdouble => "long double",
+ };
+}
+
+var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){};
+
+pub fn main() !void {
+ const gpa = general_purpose_allocator.allocator();
+ defer std.debug.assert(general_purpose_allocator.deinit() == .ok);
+
+ const args = try std.process.argsAlloc(gpa);
+ defer std.process.argsFree(gpa, args);
+
+ if (args.len != 2) {
+ std.debug.print("Usage: {s} [target_triple]\n", .{args[0]});
+ std.process.exit(1);
+ }
+
+ const query = try std.Target.Query.parse(.{ .arch_os_abi = args[1] });
+ const target = try std.zig.system.resolveTargetQuery(query);
+
+ const stdout = std.io.getStdOut().writer();
+ inline for (@typeInfo(std.Target.CType).Enum.fields) |field| {
+ const c_type: std.Target.CType = @enumFromInt(field.value);
+ try stdout.print("_Static_assert(sizeof({s}) == {d}, \"\");\n", .{
+ c_name(c_type),
+ target.c_type_byte_size(c_type),
+ });
+ try stdout.print("_Static_assert(_Alignof({s}) == {d}, \"\");\n\n", .{
+ c_name(c_type),
+ target.c_type_alignment(c_type),
+ });
+ }
+}