Skip to content

Unexpected result of std.mem.sliceAsBytes() applied to zero-size slices #23439

@vadim-za

Description

@vadim-za

Zig Version

0.14.0-dev.2851+b074fb7dd

Steps to Reproduce and Observed Behavior

Compile and run the following code:

const std = @import("std");

pub fn main() void {
    {
        const a: [2]u32 = .{ 1, 2 };
        const slice = a[0..0];
        const bytes = std.mem.sliceAsBytes(slice);
        std.debug.print(
            "{x} {x} {x}\n",
            .{
                @intFromPtr(&a),
                @intFromPtr(slice.ptr),
                @intFromPtr(bytes.ptr),
            },
        );
    }

    {
        const s: struct {
            a: [2]void = .{ {}, {} },
            b: u8 = 0,
        } = .{};
        const slice: []const void = &s.a;
        const bytes = std.mem.sliceAsBytes(slice);
        std.debug.print(
            "{x} {x} {x}\n",
            .{
                @intFromPtr(&s.a),
                @intFromPtr(slice.ptr),
                @intFromPtr(bytes.ptr),
            },
        );
    }
}

The generated output looks like:

7ff6e64883b8 7ff6e64883b8 aaaaaaaaaaaaaaaa
7ff6e64883c0 7ff6e64883c0 aaaaaaaaaaaaaaaa

Expected Behavior

The three addresses are equal in each case.

NB. The current behavior is apparently intended, as the code of std.mem.sliceAsBytes() contains explicit if's for the cases of zero-length and zero-element size slices. This behavior is however highly unexpected. It gets critical if one uses byte slices to e.g. represent memory ranges occupied by Zig entities, where for zero-size entities one gets incorrect addresses. This might even not be immediately noticed (if zero-size entities occur rarely) an lead to subtle bugs in the respective code. At any rate, if this behavior is really intended, it must be explicitly documented.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions