: (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 int
s, 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 theencoding/json
package, detailed atjson.Marshal()
xml
- used by theencoding/xml
package, detailed atxml.Marshal()
bson
- used by gobson, detailed atbson.Marshal()
; also by the mongo-go driver, detailed at bson package docprotobuf
- used bygithub.com/golang/protobuf/proto
, detailed in the package docyaml
- used by thegopkg.in/yaml.v2
package, detailed atyaml.Marshal()
db
- used by thegithub.com/jmoiron/sqlx
package; also used bygithub.com/go-gorp/gorp
packageorm
- used by thegithub.com/astaxie/beego/orm
package, detailed at Models – Beego ORMgorm
- used bygorm.io/gorm
, examples can be found in their docsvalid
- used by thegithub.com/asaskevich/govalidator
package, examples can be found in the project pagedatastore
- used byappengine/datastore
(Google App Engine platform, Datastore service), detailed at Propertiesschema
- used bygithub.com/gorilla/schema
to fill astruct
with HTML form values, detailed in the package docasn
- used by theencoding/asn1
package, detailed atasn1.Marshal()
andasn1.Unmarshal()
csv
- used by thegithub.com/gocarina/gocsv
packageenv
- used by thegithub.com/caarlos0/env
package
Related Topics
Force to Link Against Unused Shared Library
How to Prevent Paging for One Program/Process
About the Binary Compatibility of Linux
Comparing Arrays for Equality in C++
Is C/C++ Bool Type Always Guaranteed to Be 0 or 1 When Typecast'Ed to Int
How to Render an Opengl Frame in C++ Builder
Efficient Way to Determine Number of Digits in an Integer
How to Use Std::Sort to Sort an Array in C++
Invalid Conversion from 'Void*' to 'Char*' When Using Malloc
Difference Between Pointer and Reference as Thread Parameter
Best Documentation for Boost:Asio
Printing All Environment Variables in C/C++
How to Force Linker to Use Shared Library Instead of Static Library