I want to convert constant array of floats into a slice of structs. I know that the returning pointer to the current stack frame will not work. Therefore i use #force_inline, expecting that slice data will be stored in the callers stack frame. But it doesn’t work and I get this error:
Error: Cannot assign value 'raw_data(&varr)' of type '[^]Vertex_Attributes' to '[]Vertex_Attributes' in return statement
return raw_data(&varr)
^~~~~~~~~~~~~~^
Vertex_Attributes :: struct {
pos: vec3,
uv: vec2,
}
to_vertex_attributes :: #force_inline proc(arr: $T/[$N]f32) -> []Vertex_Attributes {
varr := transmute([N/5]Vertex_Attributes)arr
return varr[:]
}
main :: proc() {
data := [?]f32{
1, 2, 3, 4, 5,
1, 2, 3, 4, 5,
}
vas := to_vertex_attributes(data)
for va in vas {
fmt.println(va)
}
}
Am i missing something? Because i think i did similar thing in zig with “inline” keyword, and it just worked
P.s.
I solved my goal with a different approach:
to_vertex_attributes :: proc(fs: []f32) -> []Vertex_Attributes {
varr := cast([^]Vertex_Attributes)raw_data(fs)
return varr[:len(fs)/5]
}
main :: proc() {
data := []f32{
1, 2, 3, 4, 5,
1, 2, 3, 4, 5,
}
vas := to_vertex_attributes(data)
for va in vas {
fmt.println(va)
}
}
But i still curious on how to make first version to work…
#force_inline
doesn’t semantically inline it (and in fact, -o:none
/-debug
builds still won’t actually inline it, for instance). The semantics don’t change, and returning a pointer to stack memory isn’t valid even in a #force_inline
proc.
Reinterpreting the original data, as your updated example is doing, is a solid way of doing it. That also means you don’t have to make a copy of your data. You may also want to take a look at mem.slice_data_cast
and slice.reinterpret
, which both do the same thing, including recalculating the slice length based on the sizes of the source/destination types.
to_vertex_attributes :: proc(fs: []f32) -> []Vertex_Attributes {
return slice.reinterpret([]Vertex_Attributes, fs)
}
The closest you can do to the original approach, I think (since N/5
can’t be used in the return type), would be to pass in a pointer to where to store the copied vertex attributes and let the caller control it.
3 Likes
@Barinzaya thank you again! your answers are very helpful
