4

Suppose I have a byte structure, like this :

struct one_byte
{
char b1 : 1,
     b2 : 1,   
     b3 : 1,   
     b4 : 1,   
     b5 : 1,   
     b6 : 1,   
     b7 : 1,   
     b8 : 1;   
}foo;

In some cases I'll need to check (foo == 0), then I have to do eight commands :

if(foo.b1 == 0 &&
   foo.b2 == 0 &&
   foo.b3 == 0 &&
...and so on

Is there any portable & convenient way which can instantly check zero value only with a single command? I tried functions & templates, they perform very slowly. And I tried union, my compiler doesn't support bit[array]....

ThinkingStiff
  • 64,767
  • 30
  • 146
  • 239

6 Answers6

1

Use union, this is what it is intended for

union {
  struct {
    char b1:1,b2:1,b3:1,b4:1,b5:1,b6:1,b7:1,b8:1; 
  } bits;
  unsigned char byte;
} u;

then you can either assign directly the byte

u.byte = 15;

or the bits individually

u.bits.b3 = 1;

Exemple

int main() {
  u.byte = 0;
  printf("%x\n", u.byte);
  u.bits.b3 = 1;
  u.bits.b4 = 1;
  printf("%x\n", u.byte);
  return 0;
}

will output

0
c  // 12 in decimal, since b3 and b4 are set to 1
Community
  • 1
  • 1
Déjà vu
  • 28,223
  • 6
  • 72
  • 100
1
struct one_byte zero = { 0 };

!memcmp (&variable_1, &zero, sizeof (struct one_byte))

Could be a solution, but I don't know if it is such a clever idea. Maybe just unsing the more or less standard way of bit-setting would do better:

#define SET_BIT(v, n) (v) |= (1<<n)
#define CLR_BIT(v, n) (v) &= ~(1<<n)
#define GET_BIT(v, n) ((v) & ~(1<<n) == 0)

char foo;

if (foo == 0)
   so_what ();
mikyra
  • 10,077
  • 1
  • 40
  • 41
0

I don't think this will provide any significant performance increase.

if (memcmp(&foo, "\0", 1) == 0)
{
    // all zero
}

I don't have the C++ spec on hand but the C99 spec 6.7.2.1/13 says (emphasis mine):

Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.

dreamlax
  • 93,976
  • 29
  • 161
  • 209
  • 2
    `memcmp` isn't a good idea, because of padding bytes while alignment. In general, not in this particular case – borisbn Feb 11 '13 at 03:53
  • @borisbn: There can be **NO** padding at the beginning of a struct, only *between* members or at the end. – dreamlax Feb 11 '13 at 04:37
  • 1
    In this **particular case** - when you copmare only 1 byte - my comment has no sense, and of course, there couldn't be padding bytes at the beginning of the struct/union. But in general, it would be better to avoid `memcmp`. Do you agree ? – borisbn Feb 11 '13 at 08:10
  • You could compare against a `one_byte` with all fields zeroed to avoid the problem that @borisbn has pointed out. – wizzwizz4 May 27 '17 at 10:53
0
#include <iostream>
#include <cstring>

using namespace std;
struct one_byte{
  char b1:1;
  char b2:1;
  char b3:1;
  char b4:1;
  char b5:1; 
  char b6:1;
  char b7:1;
  char b8:1;
    }__attribute__((packed));

int main(int argc, char *argv[])
{
  one_byte b1;
  int j;
  memcpy(&j, &b1, sizeof(b1)); 
  if(j == 0) cout << "Its 0";
  else cout << "It's not 0";
  return 0;
}

what about the above program?

Aniket Inge
  • 25,375
  • 5
  • 50
  • 78
0
!*((unsigned char *) &foo)

Should do the trick. Notice that I used the ! operator to check for zero value -- if you don't like that, feel free to use == 0 instead.

aaaaaa123456789
  • 5,541
  • 1
  • 20
  • 33
0

Sounds like you want to get down and dirty, so how about:

struct one_byte Other; // a real variable
...   
if(*(char*)&Other == '\0')
Ron Burk
  • 6,058
  • 1
  • 18
  • 20
  • aaaaa... is right: unsigned is more portable, although it's hard to say "portable" with a straight face when we've already stooped this low :-) – Ron Burk Feb 11 '13 at 03:47