":" (Colon) in C Struct - What Does It Mean

: (colon) in C struct - what does it mean?

Those are bit fields. Basically, the number after the colon describes how many bits that field uses. Here is a quote from MSDN describing bit fields:

The constant-expression specifies the width of the field in bits. The
type-specifier for the declarator must be unsigned int, signed int, or
int, and the constant-expression must be a nonnegative integer value.
If the value is zero, the declaration has no declarator. Arrays of bit
fields, pointers to bit fields, and functions returning bit fields are
not allowed. The optional declarator names the bit field. Bit fields
can only be declared as part of a structure. The address-of operator
(&) cannot be applied to bit-field components.

Unnamed bit fields cannot be referenced, and their contents at run
time are unpredictable. They can be used as "dummy" fields, for
alignment purposes. An unnamed bit field whose width is specified as 0
guarantees that storage for the member following it in the
struct-declaration-list begins on an int boundary.

This example defines a two-dimensional array of structures named screen.

struct 
{
unsigned short icon : 8;
unsigned short color : 4;
unsigned short underline : 1;
unsigned short blink : 1;
} screen[25][80];

Edit: another important bit from the MSDN link:

Bit fields have the same semantics as the integer type. This means a
bit field is used in expressions in exactly the same way as a variable
of the same base type would be used, regardless of how many bits are
in the bit field.

A quick sample illustrates this nicely. Interestingly, with mixed types the compiler seems to default to sizeof (int).

  struct
{
int a : 4;
int b : 13;
int c : 1;
} test1;

struct
{
short a : 4;
short b : 3;
} test2;

struct
{
char a : 4;
char b : 3;
} test3;

struct
{
char a : 4;
short b : 3;
} test4;

printf("test1: %d\ntest2: %d\ntest3: %d\ntest4: %d\n", sizeof(test1), sizeof(test2), sizeof(test3), sizeof(test4));

test1: 4

test2: 2

test3: 1

test4: 4

What does a colon in a struct declaration mean, such as :1, :7, :16, or :32?

The 1 and the 7 are bit sizes to limit the range of the values. They're typically found in structures and unions. For example, on some systems (depends on char width and packing rules, etc), the code:

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

creates an 8-bit value, one bit for a and 7 bits for b.

Typically used in C to access "compressed" values such as a 4-bit nybble which might be contained in the top half of an 8-bit char:

typedef struct {
unsigned char leftFour : 4;
unsigned char rightFour : 4;
} tTwoNybbles;

For the language lawyers amongst us, the 9.6 section of the C++11 standard explains this in detail, slightly paraphrased:


Bit-fields [class.bit]

A member-declarator of the form

     identifieropt   attribute-specifieropt   :   constant-expression

specifies a bit-field; its length is set off from the bit-field name by a colon. The optional attribute-specifier appertains to the entity being declared. The bit-field attribute is not part of the type of the class member.

The constant-expression shall be an integral constant expression with a value greater than or equal to zero. The value of the integral constant expression may be larger than the number of bits in the object representation of the bit-field’s type; in such cases the extra bits are used as padding bits and do not participate in the value representation of the bit-field.

Allocation of bit-fields within a class object is implementation-defined. Alignment of bit-fields is implementation-defined. Bit-fields are packed into some addressable allocation unit.

Note: bit-fields straddle allocation units on some machines and not on others. Bit-fields are assigned right-to-left on some machines, left-to-right on others. - end note

What does the colon mean in struct declarations in C?

It is C++ syntax and equivalent to this:

class texmacs_input_rep : public concrete_struct {
public:
...
};

This is the normal syntax for inheritance of classes, here texmacs_input_rep is inherited from concrete_struct.

About that syntax in C:

The C-Standard you linked to defines (6.7.2.1):


struct-or-union-specifier:
struct-or-union identifieropt { struct-declaration-list }
struct-or-union identifier

struct-or-union:
struct
union

So according to C it must be struct, followed by an optional identifer, followed by {. Or only struct followed by an identifer (a forward declaration). In neither case there is room for an additional : ... in there.

The : mentioned later in that paragraph of the standard is about bit-field widths, like this;

struct foo {
unsigned a : 4;
unsigned b : 3;
};

Here a and b are only 4 and 3 bits wide, but that's different syntax than in the question.

Why does this code contains colon in struct?

The : operator is being used for bit fields, that is, integral values that use the specified number of bits of a larger space. These may get packed together into machine words to save space, but the actual behavior is implementation defined.

Now, the question "what should be the output of the sizeof operator" is straightforward but the answer is complicated.

The sizeof operator says it returns the number of bytes, but the definition of "bytes" is not necessarily what you think it is. A byte must be at least 8 bits, but could be more than that. 9, 12, and 16 bits are not unheard of.

sizeof(int) for a given platform can vary depending on the architecture word size. Assuming a byte size of 8 bits, sizeof(int) might be 2, 4, or 8. Possibly more. With a byte size of 16, sizeof(int) could actually be 1.

Now, remember I said that whether the bit fields get packed is implementation dependent? Well, that will make a big difference here. Each bit field could get put into a separate word. Or they all may be packed into one.

Most likely, you're on an Intel platform with 8-bit bytes and 32 or 64 bit ints, and the compiler will probably pack the bit fields. Therefore your sizeof(bit1) is likely to be 4 or 8.

In C, what does a colon mean inside a declaration?

It's a bitfield member. Your code means dumpable occupies exactly 1 bit in the structure.

Bitfields are used when you want to pack members in bit-level. This can greatly reduce the size of memory used when there are a lot of flags in the structure. For example, if we define a struct having 4 members with known numeric constraint

0 < a < 20
b in [0, 1]
0 < c < 8
0 < d < 100

then the struct could be declared as

struct Foo {
unsigned a : 5; // 20 < 2^5 = 32
unsigned b : 1; //
unsigned c : 3; //
unsigned d : 7; // 100 < 2^7 = 128
};

then the bits of Foo may be arranged like

                      ddddddd c  cc b aaaaa
--------- --------- --------- ----------
octet 1 octet 0
===========================================
uint32

instead of

struct Foo {
unsigned a;
unsigned b;
unsigned c;
unsigned d;
};

in which many bits are wasted because of the range of values

# wasted space which is not used by the program
# v v
ddddddd ccc
------------------------------------ ------------------------------------
uint32 uint32


b aaaaa
------------------------------------ ------------------------------------
uint32 uint32

so you can save space by packing many members together.

Note that the C standard doesn't specify how the bitfields are arranged or packed within an "addressable storage unit". Also, bitfields are slower compared with direct member access.

what does colon in the following C++ code means

This is known as a Bit Field. The expression unsigned int successor : 1; declares an unsigned int named successor of which you expect to use only 1 bit.

The behavior of using a bit field in a way that would require the use of more bits than was specified is implementation-defined behavior. It's also impossible to get a pointer or non-const reference to a bit field, since they do not necessarily begin at the beginning of a byte.

Bit fields allow compilers to reduce the size of a type in some cases by packing compatible bit fields together. Bit fields are non-binding in terms of size reduction and are only an opportunity for the compiler.

Use of the : operator in C

They're bit-fields, an example being that unsigned int addr:9; creates an addr field 9 bits long.

It's commonly used to pack lots of values into an integral type. In your particular case, it defining the structure of a 32-bit microcode instruction for a (possibly) hypothetical CPU (if you add up all the bit-field lengths, they sum to 32).

The union allows you to load in a single 32-bit value and then access the individual fields with code like (minor problems fixed as well, specifically the declarations of code and test):

#include <stdio.h>

struct microFields {
unsigned int addr:9;
unsigned int cond:2;
unsigned int wr:1;
unsigned int rd:1;
unsigned int mar:1;
unsigned int alu:3;
unsigned int b:5;
unsigned int a:5;
unsigned int c:5;
};

union micro {
unsigned int microCode;
struct microFields code;
};

int main (void) {
int myAlu;
union micro test;
test.microCode = 0x0001c000;
myAlu = test.code.alu;
printf("%d\n",myAlu);
return 0;
}

This prints out 7, which is the three bits making up the alu bit-field.

What does the :: mean in C++?

:: is the scope resolution operator - used to qualify names. In this case it is used to separate the class AirlineTicket from the constructor AirlineTicket(), forming the qualified name AirlineTicket::AirlineTicket()

You use this whenever you need to be explicit with regards to what you're referring to. Some samples:

namespace foo {
class bar;
}
class bar;
using namespace foo;

Now you have to use the scope resolution operator to refer to a specific bar.

::foo::bar is a fully qualified name.

::bar is another fully qualified name. (:: first means "global namespace")

struct Base {
void foo();
};
struct Derived : Base {
void foo();
void bar() {
Derived::foo();
Base::foo();
}
};

This uses scope resolution to select specific versions of foo.

What are the use(s) for struct tags in Go?

A tag for a field allows you to attach meta-information to the field which can be acquired using reflection. Usually it is used to provide transformation info on how a struct field is encoded to or decoded from another format (or stored/retrieved from a database), but you can use it to store whatever meta-info you want to, either intended for another package or for your own use.

As mentioned in the documentation of reflect.StructTag, by convention the value of a tag string is a space-separated list of key:"value" pairs, for example:

type User struct {
Name string `json:"name" xml:"name"`
}

The key usually denotes the package that the subsequent "value" is for, for example json keys are processed/used by the encoding/json package.

If multiple information is to be passed in the "value", usually it is specified by separating it with a comma (','), e.g.

Name string `json:"name,omitempty" xml:"name"`

Usually a dash value ('-') for the "value" means to exclude the field from the process (e.g. in case of json it means not to marshal or unmarshal that field).

Example of accessing your custom tags using reflection

We can use reflection (reflect package) to access the tag values of struct fields. Basically we need to acquire the Type of our struct, and then we can query fields e.g. with Type.Field(i int) or Type.FieldByName(name string). These methods return a value of StructField which describes / represents a struct field; and StructField.Tag is a value of type [StructTag] 6 which describes / represents a tag value.

Previously we talked about "convention". This convention means that if you follow it, you may use the StructTag.Get(key string) method which parses the value of a tag and returns you the "value" of the key you specify. The convention is implemented / built into this Get() method. If you don't follow the convention, Get() will not be able to parse key:"value" pairs and find what you're looking for. That's also not a problem, but then you need to implement your own parsing logic.

Also there is StructTag.Lookup() (was added in Go 1.7) which is "like Get() but distinguishes the tag not containing the given key from the tag associating an empty string with the given key".

So let's see a simple example:

type User struct {
Name string `mytag:"MyName"`
Email string `mytag:"MyEmail"`
}

u := User{"Bob", "bob@mycompany.com"}
t := reflect.TypeOf(u)

for _, fieldName := range []string{"Name", "Email"} {
field, found := t.FieldByName(fieldName)
if !found {
continue
}
fmt.Printf("\nField: User.%s\n", fieldName)
fmt.Printf("\tWhole tag value : %q\n", field.Tag)
fmt.Printf("\tValue of 'mytag': %q\n", field.Tag.Get("mytag"))
}

Output (try it on the Go Playground):

Field: User.Name
Whole tag value : "mytag:\"MyName\""
Value of 'mytag': "MyName"

Field: User.Email
Whole tag value : "mytag:\"MyEmail\""
Value of 'mytag': "MyEmail"

GopherCon 2015 had a presentation about struct tags called:

The Many Faces of Struct Tags (slide) (and a video)

Here is a list of commonly used tag keys:

  • json      - used by the encoding/json package, detailed at json.Marshal()
  • xml       - used by the encoding/xml package, detailed at xml.Marshal()
  • bson      - used by gobson, detailed at bson.Marshal(); also by the mongo-go driver, detailed at bson package doc
  • protobuf  - used by github.com/golang/protobuf/proto, detailed in the package doc
  • yaml      - used by the gopkg.in/yaml.v2 package, detailed at yaml.Marshal()
  • db        - used by the github.com/jmoiron/sqlx package; also used by github.com/go-gorp/gorp package
  • orm       - used by the github.com/astaxie/beego/orm package, detailed at Models – Beego ORM
  • gorm      - used by gorm.io/gorm, examples can be found in their docs
  • valid     - used by the github.com/asaskevich/govalidator package, examples can be found in the project page
  • datastore - used by appengine/datastore (Google App Engine platform, Datastore service), detailed at Properties
  • schema    - used by github.com/gorilla/schema to fill a struct with HTML form values, detailed in the package doc
  • asn       - used by the encoding/asn1 package, detailed at asn1.Marshal() and asn1.Unmarshal()
  • csv       - used by the github.com/gocarina/gocsv package
  • env - used by the github.com/caarlos0/env package


Related Topics



Leave a reply



Submit