Ask HN: Why is this C code not working as intended?

2 points by klingonopera ↗ HN
These two functions

    unsigned int M1ByteMirror(unsigned int iNumber) {
        unsigned int lVal = M1GetN3(iNumber);
        lVal |= M1GetN2(iNumber) << 8;
        lVal |= M1GetN1(iNumber) << 16;
        lVal |= M1GetN0(iNumber) << 24;
        return lVal;
    }

    unsigned int M1ByteMirrorSingle(unsigned int iNumber) {
        unsigned int lVal = (M1GetN3(iNumber) | (M1GetN2(iNumber) << 8) | (M1GetN1(iNumber) << 16) | (M1GetN0(iNumber << 24)));
        return lVal;
    }
are logically the same, yet the output is:

  random data: baa206c, mirror: 6c20aa0b, single: 20aa0b
Why is the compiler/C ignoring the last function call in the single line declaration? Is there a typo/mistake I missed or is there something deeper going on?

EDIT: Or is this just my setup? MinGW32, Win7 x64 Ult SP1, i5 6600K.

EDIT2: I had -O2 on, turned it off, same results, but holy crap, is optimization effective.

4 comments

[ 3.5 ms ] story [ 9.4 ms ] thread
(M1GetN0(iNumber << 24))

You have a typo in the second function.

Ahhhhhhhhhhh.....

EDIT: Thank you, and case closed.

Sidenote: Is there a possibility, however, that the single-line declaration may fail at runtime, if RAM is low? Most likely not on an x86-PC, but an Arduino with 2K RAM?

I had a similar issue with some Arduino code four years ago, and it could've also just been a typo, but I could've sworn the less than ~500 byte SRAM left available wouldn't allow me to call too many functions per ..."instruction"(?).

The source code[1] of what I was working on.

It's a simple benchmark, to see what the quicker way to access data byte-wise from a uint32_t in C is, between bit-shifting and masking or indirect access via pointer declaration/de-referencing, and also between a single-line declaration or a multi-lined declaration as per original topic question.

The results behave as expected when turning on and off optimizations, but their relative comparison is highly dependent on it. It means that bit-shifting is faster, but only with optimizations. A multi-lined declaration may be as fast as a single-lined declaration, but also only with optimizations.

[1] : https://morgen.ist/misc/Simple-Byte-Access-Benchmark.c