3 ms·
Can someone explain further why this is so hard? I’m not familiar enough with any of this to understand without some help.
by mwint 5y ago
Can someone explain further why this is so hard? I’m not familiar enough with any of this to understand without some help.
- ncmncm 5y agoIt is just very finicky, with myriad edge cases easy to get wrong, and even easier to neglect to have complete tests for. Each target CPU design and version has quirks. Many involve sign extension.
- jstimpfle 5y agoExtracting a subrange of bits and shifting them to the beginning is not exactly rocket science.
- ncmncm 5y agoExperience indicates otherwise. If you must use bit fields, make them unsigned. Bugs love to hide under signed bit fields.
- jstimpfle 5y agoThat makes sense, looking at how signed arithmetic works on different architectures it would feel strange to use signed bitfields. Unsigned bitfields are a nice way to get modular arithmetic with n bits without syntactic clutter.
- ncmncm 5y ago"Unsigned bitfields are a nice ..." Appear to be. Are, when all the stars align. Are not in fact, often enough that you are issued a red warning you may ignore if you are insulated from all consequences.
- jcranmer 5y agoThere's a few layers of complexity here. The first is lvalues. In compiler jargon, an lvalue is a kind of object that can have a value stored to it. And you can usually represent it as the address of some memory location [1]. Of course, bitfields break this representation: you need to know what the bit offset and bit size of the field you're storing is (as well as the signedness). The next level of complexity is the conditional operator. This means that, when conditional operators yield lvalues [2], you now end up in a situation where the lvalue now has a conditional bit offset and bit size within the address. Or maybe one leg of the expression returns a bit-field and the other leg returns a regular int lvalue. Imagine how complex your datastructure needs to be to represent an lvalue during this code generation phase. [1] Not all lvalues need to have memory locations. But if you're writing a C compiler, it's an easy first approximation to give every variable, even those marked register, some memory location and rely on an optimization pass to convert stack memory locations into register locations, rather than keeping track of this information when the frontend does code generation. [2] As mentioned elsewhere, conditional operators in C do not yield lvalues. But conditional operators in C++ do.