so, I was writing a store for dynamic value (just a wrapper for std.HashMap) and found out that you can modify a const value by passing its pointer then doing a asBytes()
the file here [should I paste it here]
// بسم الله الرحمن الرحيم
// la ilaha illa Allah Mohammed Rassoul Allah
map: std.StringArrayHashMap([]u8),
pub fn init(allocator: std.mem.Allocator) Self {
return .{
.map = .init(allocator),
};
}
pub fn deinit(self: *Self, allocator: std.mem.Allocator) void {
var iter = self.map.iterator();
while (iter.next()) |entry| allocator.free(entry.value_ptr.*);
self.map.deinit();
}
/// adds the value itself to the map after duping it
///
/// calling it like `try map.add("123", 123, allocator);`
/// whill store a heap allocated int
pub fn add(self: *Self, key: []const u8, value: anytype, allocator: std.mem.Allocator) !void {
const slice: []const u8 = std.mem.asBytes(&value);
const slice_allocated: []u8 = try allocator.dupe(u8, slice);
errdefer allocator.free(slice_allocated);
try self.map.put(key, slice_allocated);
}
pub fn get(self: *Self, key: []const u8) ?[]u8 {
return self.map.get(key);
}
pub fn getAs(self: *Self, key: []const u8, T: type) ?*T {
const raw: []u8 = self.map.get(key) orelse return null;
const ptr: *T = @alignCast(std.mem.bytesAsValue(T, raw));
return ptr;
}
test "multiple types" {
const testing = std.testing;
var store: Self = .init(testing.allocator);
defer store.deinit(testing.allocator);
var a: u32 = 31;
try store.add("a", a, testing.allocator);
try store.add("a_ptr", &a, testing.allocator);
const a_entry: *u32 = store.getAs("a", u32) orelse unreachable;
a_entry.* = 0;
try testing.expect(a == 31);
try testing.expect(a_entry.* == 0);
const a_ptr_entry: **u32 = store.getAs("a_ptr", *u32) orelse unreachable;
a_ptr_entry.*.* = 8;
try testing.expect(a_entry.* == 0);
try testing.expect(a_ptr_entry.* != a_entry);
try testing.expectEqual(a_ptr_entry.*, &a);
try testing.expectEqual(a, 8);
}
const Self = @This();
const std = @import("std");
I get error: 'store.test.multiple types' failed: expected 31, found 8 unless I change const a: u32 = 31; to var a: u32 = 31;
the question is:
why does try testing.expectEqual(a_ptr_entry.*, &a); pass and at the same time try testing.expectEqual(a, 8); fails? I assume that for the latter it checks for a at comptime because a is a const so any modifications to it might be a programmer bug.
final note
dis is a programmer’s fault probably, idk if this is allowed to be considered a bug. it’s just: idk.