Next: Struct Comparison, Previous: Struct Types, Up: Structs [Contents][Index]
Once a struct type gets defined, there are two ways to build struct values from it. One is mapping. See Mapping Structs. The other is using a struct constructor, which is explained in this section.
Struct constructors have the following form:
type_name { [field_initializer,]… }
where each field_initializer has the form:
[field_name=]exp
Note how each field has an optional name field_name and a value exp. The expression for the value can be of any type. For convenience, a trailing comma is accepted but not required.
Suppose for example that we have a type defined as:
type Packet =
struct
{
uint<16> flags;
byte[32] data;
}
We can construct a new packet, with all its fields initialized to zero, like this:
(poke) Packet {}
Packet {
flags=0x0UH,
data=[0x0UB,0x0UB,0x0UB,0x0UB,0x0UB,…]
}
In the constructor we can specify initial values for some of the fields:
(poke) Packet { flags = 0x8 }
Packet {
flags=0x8UH,
data=[0x0UB,0x0UB,0x0UB,0x0UB,0x0UB,…]
}
It is not allowed to specify initializers that are not part of the type being constructed:
(poke) Packet { foo = 10 }
<stdin>:1:10: error: invalid struct field `foo' in constructor
Packet { foo = 10 };
^~~
As we shall see later, many struct types define constraints on the values their fields can hold. This is a way to implement data integrity. While building struct values using constructors, these constraints are taken into account. For example, given the following struct type:
type BPF_Reg =
struct
{
uint<4> code : code < 11;
};
we will get a constraint violation exception if we try to construct an
BPF_Reg:
(poke) BPF_Reg { code = 20 }
unhandled constraint violation exception
Next: Struct Comparison, Previous: Struct Types, Up: Structs [Contents][Index]