6

I've just noticed an interesting property of gcc with regard to bit-fields. If I create a struct like the following:

template <int N>
struct C
{
    unsigned long long data : N;
};

Then on amd64:

  1. with -m64, for N ∊ <1, 64>, sizeof(C) == 8;
  2. with -m32, for N ∊ <1, 32>, sizeof(C) == 4 and for N ∊ <33, 64>, sizeof(C) == 8.

(with sizeof(unsigned long long) == 8).

That seems to mostly resemble the C99/C++11 uint_fastXX_t except for the fact that on my system sizeof(uint_fast8_t) == 1. But for example, I can't reproduce anything similar with __int128 (which always results in sizeof(C) == 16).

Does it seem like a good idea to you to use the fore-mentioned struct as a «poor man's» replacement for uint_fastXX_t in C++98?

Michał Górny
  • 18,713
  • 5
  • 53
  • 76

2 Answers2

7

No -- a bit-field will frequently be considerably slower than a bare, unadorned int, because if you do something (e.g., addition or multiplication) that might overflow the designated size, the compiler will (typically) insert a bitwise and instruction to ensure that the result fits in the specified size. E.g., if you multiply two 10-bit numbers and put the result in a 10-bit field, the multiplication may produce up to a 20-bit number, so the compiler will normally produce the 20-bit result, the use a bitwise and to get the 10 least significant bits for the result.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
3

Not really. On most systems we care about, uint_fast32_t, uint_least32_t, and uint32_t will be the same type.

It is only on exotic hardware the fast/least types might be 36 bits, for example, instead of 32.

Community
  • 1
  • 1
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
  • So, you don't care about 64-bit systems or am I misunderstanding your intentions? – Michał Górny Aug 18 '12 at 21:42
  • 1
    It's just an example. Not all systems are 32- or 64-bit. On the (slightly exotic) system I linked to, `unsigned long long` would be 72 bits, but `sizeof(unsigned long long)` still 8 (with `CHAR_BIT` == 9). – Bo Persson Aug 18 '12 at 22:00
  • But say, if I need 8 bits of them for a bit-field, wouldn't an `unsigned long long:8` (or `unsigned long:8`) bit-field be more likely optimal than a random type like `char`? – Michał Górny Aug 18 '12 at 22:05