Skip to content

@memset on packed unions with over-aligned fields behaves differently under Debug vs Release #17362

@kcbanner

Description

@kcbanner

Zig Version

0.12.0-dev.700+376242e58

Steps to Reproduce and Observed Behavior

const std = @import("std");
const testing = std.testing;

test "memset packed union" {
    const U = packed union {
        a: u32,
        b: u8 align(8),
    };

    var u: U = undefined;
    @memset(std.mem.asBytes(&u), 0x2a);
    try testing.expectEqual(@as(u32, 0x2a2a2a2a), u.a);
    try testing.expectEqual(@as(u8, 0x2a), u.b);
}
$ zig test memset_packed.zig -O ReleaseFast
Test [1/1] test.memset packed union... expected 707406378, found 00
$ zig test memset_packed.zig
All 1 tests passed.

A few things seem to be required for this to happen:

  • The @memset. Replacing it with var u: U = .{ .a = 0x2a2a2a2a }; resolves the issue.
  • The alignment of the over-aligned field must be greater than the size of any other field. If you change the align(8) to align(4), or if you add a u64 field, the issue is resolved.

Expected Behavior

Consistent behaviour between Debug and Release*.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugObserved behavior contradicts documented or intended behavior

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions