#Compile error when slicing ptr to an array.

1 messages · Page 1 of 1 (latest)

lilac turret
#

Hi, I apologize for the stupid question but I'm new to zig and haven't done pointer arithmetic in a long time. I'm having a hard time with the type system. I have this concatenate function for strings:

`fn concatenate(comptime size1: usize, comptime str1: *const [size1]u8, comptime size2: usize, comptime str2: *const [size2]u8) []u8 {
const str1Slice = str1[0..size1];
const str2Slice = str2[0..size2];

const newStringSize = size1 + size2;
var newStringSlice: [newStringSize]u8 = undefined;

for (0..size1) |i| {
    newStringSlice[i] = str1Slice[i];
}

comptime var whereWeLeftOf = size1;
for (0..size2) |i| {
    newStringSlice[whereWeLeftOf] = str2Slice[i];
    whereWeLeftOf += 1;
}

return &newStringSlice;

}`

And this test function:

`test "concatenation" {
const str1: *const [5]u8 = "Love ";
const str2: *const [3]u8 = "Zig";
const expectedStr: *const [8]u8 = "Love Zig";

const newString = comptime concatenate(5, str1, 3, str2);
const expectedSlice: []u8 = expectedStr[0..8];
try std.testing.expectEqual(@as([]u8, expectedSlice), newString);

}`

for this line const expectedSlice: []u8 = expectedStr[0..8]; the compiler gives me error: expected type '[]u8', found '*const [8]u8' . My question is why obviously :). I'm using the slicing operator there. More than that I'm doing the same thing on *const []u8 's in the concatenate function.

Thanks in advance and sorry for the stupid question again 🙂

inner aspen
#

first off, const [3]u8 is not a valid type. const is redundant here as str2 is already const

#

just saying

lilac turret
#

@inner aspen Just changed the post to use backticks on the code so the * can be seen

#

my mistake

inner aspen
#

no problem. just saying, you dont need to type everything lol.
just:

const str1 = "Love ";

would be perfectly fine

lilac turret
#

Yeah, agreed, thanks. I don't mind verbosity though 🙂

inner aspen
#

now we can get back to the actual issue at hand :D
expectedStr is of type *const [8]u8. this is an array pointer. not to be confused with a slice.
when you do [0..8] on an array pointer, and it's the exact same length, nothing changes. expectedSlice will also be of type *const [8]u8

now to achieve what you actually want to do you need to use const expectedSlice: []const u8
this is beacuse as explained previously the right hand side of this expression is *const [8]u8 and casting to a []u8 would remove the const qualifier. the zig error even tells you this i believe

lilac turret
#

"when you do [0..8] on an array pointer, and it's the exact same length, nothing changes." . Never found something like that in the docs or examples. This is interesting to know. Thank you. Behaves as expected now

inner aspen
#

👍

ripe atlas
# lilac turret Hi, I apologize for the stupid question but I'm new to zig and haven't done poin...

id recommend favoring []const u8 (or [:0]const u8 if you need a 0 terminal) 99% of the time for const strings, since:

  1. *const [N]u8 is directly coercible to them
  2. you wont have to pass the lengths as theyre built into the slice type
    this would change the function signature to:
fn concatenate(comptime str1: []const u8, comptime str2: []const u8) [str1.len + str2.len]u8

ive changed the output type from a slice to an array. a slice is a pointer, and in your example you return a pointer to a local which is dangerous. the only things you would need to change in the function body are:

  1. size1/2 becomes str1/2.len
  2. remove the & on the return statement

id recommend to remove the str1/2Slice variables as they are redundant, just use str1/2 directly

also, just in case you didnt know, theres an array concatenator ++ which works on comptime known length strings ;)