# Null terminated array of strings from C function

**URL:** <https://ziggit.dev/t/null-terminated-array-of-strings-from-c-function/2459>\
**Category:** Help\
**Tags:** language, c\
**Created:** [December 14, 2023, 2:23pm UTC](https://ziggit.dev/t/null-terminated-array-of-strings-from-c-function/2459 "2023-12-14T14:23:13Z")\
**Posts on this page:** 1\
**Showing post:** 12

<div class="post-metadata">

**Author:** ![castholm](https://ziggit.dev/user_avatar/ziggit.dev/castholm/32/1330_2.png) [@castholm](https://ziggit.dev/u/castholm)\
**Post date:** [December 15, 2023, 12:19pm UTC](https://ziggit.dev/t/null-terminated-array-of-strings-from-c-function/2459/12 "2023-12-15T12:19:53Z")

</div>

The question mark goes on the left of the pointer, not the right. The list itself is not optional, but the elements (the strings) are. If we break it down:

```zig
[*:null] // many-item 'null'-terminated pointer to
        ? // optional of
         [*:0]const // many-item '0'-terminated const pointer to
                    u8 // unsigned 8-bit integer

```

Perhaps the best way to explain complicated pointer types is to use Zig itself:

```zig
comptime {
    explainType([*:null]?[*:0]const u8);
}

fn explainType(comptime T: type) void {
    comptime {
        @compileLog("Explaining " ++ @typeName(T));
        var maybe_current: ?type = T;
        while (maybe_current) |current| {
            const info = @typeInfo(current);
            @compileLog(info);
            maybe_current = switch (info) {
                inline .Array,
                .Vector,
                .Pointer,
                .Optional,
                => |parent_info| parent_info.child,
                else => null,
            };
        }
    }
}

```

Pasting this into any source file and compiling will fail the compilation but print the following useful information to the terminal:

```zig
@as(*const [33:0]u8, "Explaining [*:null]?[*:0]const u8")
@as(builtin.Type, .{ .Pointer = .{.size = .Many, .is_const = false, .is_volatile = false, .alignment = 8, .address_space = .generic, .child = ?[*:0]const u8, .is_allowzero = false, .sentinel = null} })
@as(builtin.Type, .{ .Optional = .{.child = [*:0]const u8} })
@as(builtin.Type, .{ .Pointer = .{.size = .Many, .is_const = true, .is_volatile = false, .alignment = 1, .address_space = .generic, .child = u8, .is_allowzero = false, .sentinel = 0} })
@as(builtin.Type, .{ .Int = .{.signedness = .unsigned, .bits = 8} })

```

---

_[View the full topic](https://ziggit.dev/t/null-terminated-array-of-strings-from-c-function/2459)._
