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 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]