Passing a string to a function

I was going to start with a very basic program to learn functions and error handling but am stuck on the most basic thing and can’t seem to get past it. I have looked up other examples that look exactly like my code and supposedly work, but my program doesn’t. Could someone please help? I also tried to declare the function parameter as a const but get other error message when I do that.

I think my largest problem with zig atm is the compiler isn’t very helpful when reporting errors. This program gives main.zig:6:10: error: expected type ‘u8’, found ‘*const [5:0]u8’
Test(name);

I thought strings are all arrays of u8?

pub fn main() !void {
    const name = "Smith";
    Test(name);
}

fn Test(name: []u8) void {
    print("hello {}\n", .{name});
}

Hey,

When you try to compile your program you see the following error.

src/main.zig:9:10: error: expected type '[]u8', found '*const [5:0]u8'
    Test(name);
         ^~~~
src/main.zig:9:10: note: cast discards const qualifier
src/main.zig:3:15: note: parameter type declared here
fn Test(name: []u8) void {
              ^~~~

At which point you should notice that you need a const added to your function.

fn Test(name: []const u8) void {
    std.debug.print("hello {}\n", .{name});
}

pub fn main() !void {
    const name = "Smith";
    Test(name);
}

Which produces another error.

/home/jud/zig/lib/std/fmt.zig:632:21: error: cannot format slice without a specifier (i.e. {s} or {any})
                    @compileError("cannot format slice without a specifier (i.e. {s} or {any})");
                    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Which tells you you need to provide the specifier for string.

Which results in.

const std = @import("std");

fn Test(name: []const u8) void {
    std.debug.print("hello {s}\n", .{name});
}

pub fn main() !void {
    const name = "Smith";
    Test(name);
}

I encourage you to take your time with the compiler and try to reason about what it’s telling you.

In both cases it more or less points to your problem.

I hope my post encourages you to continue to program in Zig should you find it enjoyable. Prepare yourself for more interactions with the compiler like this though.

2 Likes

And yes a string is usually depicted as just a slice of u8 when using zig. A string literal is a special string though and it gets a const. See this for more

If you wanted an example of a non const “string” in zig you can do array list things. (not that this really makes sense I’m just giving you and example)

const std = @import("std");

fn Test(name: []u8) void {
    std.debug.print("hello {s}\n", .{name});
}

pub fn main() !void {
    var buffer: [1024]u8 = undefined;
    var FBA = std.heap.FixedBufferAllocator.init(&buffer);
    // some non const array of u8
    var example: std.ArrayList(u8) = std.ArrayList(u8).init(FBA.allocator());
    try example.appendSlice("Smith");
    Test(example.items);
}

Thank you. Now that I know what to look for I’ll pay more attention. I had changed my function to receive a const but the second error didn’t provide a line number and I missed the fact that I needed the “s” inside the print.

Thanks again,

Glenn