ERROR: array literal requires address-of operator (&) to coerce to slice type '[][]const u8'

I am too stupid ig, would appreciate some help.

const ABC = [_][]const u8{
    "one", "two", "three",
};

fn returnABC() [][]const u8 {
    return ABC;
}

test "testing returnABC" {
    try testing.expect(returnABC() == ABC);
}

Why is a simple code like this failing with error

error: array literal requires address-of operator (&) to coerce to slice type '[][]const u8'

Adding & worsens the error, I dont properly understand the pointer situation in zig, Im not getting anything related on google

Here’s one way of doing this:

const std = @import("std");

const ABC = [_][]const u8{
    "one", "two", "three",
};

fn returnABC() []const []const u8 {
    return ABC[0..];
}

test "testing returnABC" {
    try std.testing.expect(std.meta.eql(returnABC(), ABC[0..]));
}
1 Like

Note that [_][]const u8 and [][]const u8 are completly different things, despite looking similar.
Generally [_]T is an array of compile-time known length.
[]T is a slice, which is a pointer to an array of runtime-known length.
A slice is basically a struct{ptr: [*]T, len: usize} with some syntactic sugar.

Now to make an array into a pointer to an array, you need to use the address-of operator &.
In your case &ABC. This will give you a *const [3][]const u8.
This can coerce to a slice []const []const u8

Now your second problem is constness. You said that ABC is const.
Therefore its pointer, &ABC must be pointer to constant memory.
You however want to a [][]const u8 which is a mutable(!) slice of []const u8.

Now your third problem is that == is not available for slices. You can however compare it element-wise:

const a = returnABC();
try std.testing.expect(a.ptr == &ABC and a.len == ABC.len);

Or for convenience you can use std.meta.eql

3 Likes