master
 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 cName(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(.{}) = .init;
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    var threaded: std.Io.Threaded = .init(gpa);
43    defer threaded.deinit();
44    const io = threaded.io();
45
46    const query = try std.Target.Query.parse(.{ .arch_os_abi = args[1] });
47    const target = try std.zig.system.resolveTargetQuery(io, query);
48
49    var buffer: [2000]u8 = undefined;
50    var stdout_writer = std.fs.File.stdout().writerStreaming(&buffer);
51    const w = &stdout_writer.interface;
52    inline for (@typeInfo(std.Target.CType).@"enum".fields) |field| {
53        const c_type: std.Target.CType = @enumFromInt(field.value);
54        try w.print("_Static_assert(sizeof({0s}) == {1d}, \"sizeof({0s}) == {1d}\");\n", .{
55            cName(c_type),
56            target.cTypeByteSize(c_type),
57        });
58        try w.print("_Static_assert(_Alignof({0s}) == {1d}, \"_Alignof({0s}) == {1d}\");\n", .{
59            cName(c_type),
60            target.cTypeAlignment(c_type),
61        });
62        try w.print("_Static_assert(__alignof({0s}) == {1d}, \"__alignof({0s}) == {1d}\");\n\n", .{
63            cName(c_type),
64            target.cTypePreferredAlignment(c_type),
65        });
66    }
67    try w.flush();
68}