← Back to context

Comment by mtklein

1 day ago

This was my instinct too, until I got this little tickle in the back of my head that maybe I remembered that Clang was already acting like this, so maybe it won't be so bad. Notice 32-bit wzr vs 64-bit xzr:

    $ cat union.c && clang -O1 -c union.c -o union.o && objdump -d union.o
    union foo {
        float  f;
        double d;
    };

    void create_f(union foo *u) {
        *u = (union foo){0};
    }

    void create_d(union foo *u) {
        *u = (union foo){.d=0};
    }

    union.o: file format mach-o arm64

    Disassembly of section __TEXT,__text:

    0000000000000000 <ltmp0>:
           0: b900001f      str wzr, [x0]
           4: d65f03c0      ret

    0000000000000008 <_create_d>:
           8: f900001f      str xzr, [x0]
           c: d65f03c0      ret

Ah, I can confirm what I see elsewhere in the thread, this is no longer true in Clang. That first clang was Apple Clang 17---who knows what version that actually is---and here is Clang 20:

    $ /opt/homebrew/opt/llvm/bin/clang-20 -O1 -c union.c -o union.o && objdump -d union.o

    union.o: file format mach-o arm64

    Disassembly of section __TEXT,__text:

    0000000000000000 <ltmp0>:
           0: f900001f      str xzr, [x0]
           4: d65f03c0      ret

    0000000000000008 <_create_d>:
           8: f900001f      str xzr, [x0]
           c: d65f03c0      ret