What is the point of ":" (two points) in the statement of a member of a structure?

Asked

Viewed 1,922 times

12

I saw this:

typedef struct {
    unsigned char a : 1;
    unsigned char b : 7;
} Tipo;

What does this statement mean? What is this 1 and 7?

1 answer

16


Let’s run this code to better understand:

#include <stdio.h>

typedef struct {
    unsigned char a : 1;
    unsigned char b : 7;
} Tipo;

int main(void) {
    Tipo x = { .a = 1, .b = 64 };
    printf("%d e %d\n", x.a, x.b);
    printf("%zd\n", sizeof(Tipo));
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Try to put on the limb a a value greater than 1. It doesn’t work, it can only be 0 or 1. Already caught why?

In the second print we see that the size of this structure is 1 byte. And now, killed?

The two points are used when the structure is used to mount a bit string and each member is called bit field. So what comes after the : is the amount of bits that member contains. Hence the a can only have 0 or 1. It only has 1 bit. The same is true if you try to put more than 127 in b that only has 7 bits.

Ideally these structures should have a total multiple size of 8 to fit with a byte, but if there is no alignment according to compiler rules.

Possible members types are specified as _Bool, signed int, unsigned int and others specified by the compiler, which is what was used. It is usually best to use universally defined sized types. So it is best to have a int32_t than a int.

It is very common that this type of structure is within a larger structure with other members.

It is also very common to use with union. So you can access a union member as a single die and the other union member as a bit structure.

#include <stdio.h>

typedef union {
    char valor;
    struct {
        unsigned char a : 1;
        unsigned char b : 1;
        unsigned char c : 1;
        unsigned char d : 1;
        unsigned char e : 1;
        unsigned char f : 1;
        unsigned char g : 1;
        unsigned char : 1;
    } bits;
} Tipo;

int main(void) {
    Tipo x = { .valor = 87 };
    printf("%d %d %d %d %d %d %d", x.bits.a, x.bits.b, x.bits.c, x.bits.d, x.bits.e, x.bits.f, x.bits.g);
}

Behold working in the ideone. And in the repl it.. Also put on the Github for future reference.

Note that I showed you another point. You are not required to identify all bits. Of course, not putting a name on some bit, or set of bits, will not be able to access its value directly and named.

  • If a char has the size of 1 byte worth 8 bits, as it is possible to set 1 bit for a type variable char ? Since, it by default stores 8 bits, which in this case is the amount of bits needed to represent a symbol (character).

  • 1

    @cat because there is the guy unsigned char, is the guy unsigned char : 1, looks like the same guy, but it’s not :)

  • I didn’t understand this line either unsigned char : 1; it seems that you have declared a variable that does not contain a name, at least a name that the programmer would use to access it, and in Union Tipo you accessed all variables with names for example x.bits.a, and if I wanted to access the value of the nameless variable unsigned char : 1; of the structure bits?

  • @cat can’t do it. Obviously I just did it to demonstrate, but it’s quite useful, maybe not like the last one. This type of technique is often used to pick up parts of a number that mean something specific. To compress as much information as possible into a number of some size, it can be a number of 1 byte, 2, 4, etc. Each bit or set of bits is an independent information field. But it may be that some do not matter for your application, are there as alignment, or reserved for future use, it is not known yet for what will be used.

  • There’s no reason to name it there, but you have to declare it to say that it has these bits in the layout of the data that will be picked up and ignored by the application. You can still access this section, but not by a name, but in general if you will not give name is because you should not access. I would have to do a " calculation" by displacing bits and formulas that involve it, as I already said something in http://answall.com/q/175345/101 and many people did not find it useful :D

  • This structure Linux uses, but I don’t understand what the purpose is.

  • @I can’t say without knowing details, but it is essentially a reserve of space for future use. If you pay attention everything generates an alignment of 4 bytes, even where it has 5, then it has 3, this beginning had 3 chars, then it would be 1 byte left, since it would be allocated anyway, did explicitly http://answall.com/q/125057/101

Show 2 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.