#Initialize static array

1 messages · Page 1 of 1 (latest)

sinful birch
#

I want to initialize a static array with 0 except at some indices where I want a value. It's going to be sparse and I'd like to specifies those value as a list. I came up with this:

const std = @import("std");

fn make_tuple(comptime LHST: type, comptime RHST: type) type {
  return struct { LHST, RHST };
}

const initial_values = [_]make_tuple(usize, u32) {
  .{ 0x02, 0xFF },
  .{ 0x06, 0x42 },
};

fn init_csr(comptime T: type, values: []const make_tuple(usize, T)) [4096]T {
  var tmp = [_]T{ 0 } ** 4096;
  for (values) |value| {
    tmp[value[0]] = value[1];
  }
  return tmp;
}

pub fn main() void {
  var arr = init_csr(u32, &initial_values);
  std.debug.print("{any}", .{ arr });
}
#

It's working but very verbose. Is there a better way of doing this?

#

Couldn't get rid of make_typle because otherwise I end up with multiple anonymous types incompatible with each other.

#

Also, coudn't find a way to do that without defining a function (init_csr).

slender kindle
#

you can use a labelled block

sinful birch
#

Yes I just found another answer in another chat with that solution.

slender kindle
#
var arr = comptime blk: {
    var tmp = [_]u32{ 0 } ** 4096;
    for (values) |value| {
      tmp[value[0]] = value[1];
    }
    break :blk tmp;
};
sacred zealot
#

yup, unless if you want to have it generic. Then you need something along MakeTupleT to provide the return type or you need to infer it with anytype (better dont).

sinful birch
#

anytype is an inference or is like "shut up compiler"

#

If it's an inference, it should be ok no?

slender kindle
#

it's ducktyping

sacred zealot
slender kindle
#

so e.g., if you pass 1, it doesn't coerce to a sized integer, it will just be passed as comptime_int, which has different semantics

sacred zealot
slender kindle
#

idk about slower to compile, it shouldn't be much slower than using an comptime T: type parameter to specify the type

radiant turtle
#

it is possible to remove make_tuple by defining the tuple in the parameter and leaving initial_values with no explicit type

const std = @import("std");

const initial_values = .{
    .{ 0x02, 0xFF },
    .{ 0x06, 0x42 },
};

fn init_csr(comptime T: type, values: []const struct { usize, T }) [4096]T {
    var tmp = [_]T{0} ** 4096;
    for (values) |value| {
        tmp[value[0]] = value[1];
    }
    return tmp;
}

pub fn main() void {
    var arr = init_csr(u32, &initial_values);
    std.debug.print("{any}", .{arr});
}
#

don't know if it is that much nicer though

sacred zealot
radiant turtle
#

sure

sinful birch
#

No but I don't want that because I will have different intiaal value depending on the context. They will come from an import.

sacred zealot
sinful birch
#

This array is part of a struct create from a "functor" (not sure if its the correct word). Then in a function main I'll for const rv32 = @import("rv32.zig"); make(rv32.initial_value); and in another const rv64 = @import("rv64.zig"); make(rv64.initial_value);.

#

What I don't understand is why @radiant turtle 's solution works but specifying initial_value's type would not.

#

It's still an anonymous type. It's even more anonymous...

#

Oh because it's going to infer the type backward from the call to init_csr.

sacred zealot
sinful birch
#

Thank you all.

sinful birch
#