in reply to Re: IC problem.[Solved, (feel free to reap)]
in thread IC problem.[Solved, (feel free to reap)]

This:

typedef union { struct { unsigned sign : 1; unsigned exponent :11; U64 mantissa :52; }; double d; U64 u; } DFields;

Should be this:

typedef union { struct { U64 sign : 1; U64 exponent :11; U64 mantissa :52; }; double d; U64 u; } DFields;

Turns out that unless all the bit fields are defined to be of the same unsigned type, they will not be mapped to the same unit of memory.

I originally had them all defined as just unsigned; but the compiler complained that the mantissa was too large for a 32-bit uint. So, I switch it to U64 and it compiled.

The problem is that produces a struct that occupies more than 64-bits. The first two bitfields are merged into a U32, but because the third is a different underlying type, it gets mapped to a different chunk of uninitialised memory. Hence, the apparently random nature of the output.

Making all three fields the same type means they get amalgamated into a single 64-bit piece of ram. (But it took some searching to locate this rather arcane piece of knowledge.)


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

Replies are listed 'Best First'.
Re^3: IC problem.[Solved, (feel free to reap)]
by cavac (Prior) on Jun 12, 2015 at 12:58 UTC

    Hmm, interesting. I also would have thought that in a union-type, all variables start at offset zero.

    I thought i have seen it used something like this (pseudo-code, my C coding days are mostly over so i'm not really sure how this is all supposed to look): Image you want to have different IP records in memory, say,

    typedef struct { uint32 type; char ip[4]; } ipv4; typedef struct { uint32 type; char ip[16]; } ipv6;
    Then you would be able to have an union type of both and access the first field ("type") to cast the variable to the the correct typedef?

    As said, my C coding days are mostly over. But since i have some XS work coming up, i might as well start to think about such problems right now :-)

    "For me, programming in Perl is like my cooking. The result may not always taste nice, but it's quick, painless and it get's food on the table."
      in a union-type, all variables start at offset zero.

      They do. But the bit fields are in a struct nested inside the union. The problem I describe is unique to bit-fields; and unique to bit-fields on 64-bit.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority". I'm with torvalds on this
      In the absence of evidence, opinion is indistinguishable from prejudice. Agile (and TDD) debunked

        Thanks for the clarification.

        "For me, programming in Perl is like my cooking. The result may not always taste nice, but it's quick, painless and it get's food on the table."