p4-spec
p4-spec copied to clipboard
P4_16: Convenient initialization of header/structs
Personnel
- [x] Owner: @jafingerhut
- [x] Supporters: @liujed, @marko-stanoj
Design
- [x] Document:
Implementation
- [x]
p4-spec
: https://github.com/p4lang/p4-spec/pull/717 - [x]
p4c
: https://github.com/p4lang/p4c/pull/2368
Process
- [x] LDWG discussed:
- [x] LDWG approved:
- [x] Merged into
p4-spec
: - [ ] Merged into
p4c
:
I believe @vgurevich proposed this late before the P4_16 spec was finalized, and I do not see any issue here to track it, so wanted to add one. Feel free to mark it "Post P4_16" if that helps.
This is primarily a feature for P4 program writing convenience. The effect of initializing all fields of a header, or all fields of a struct, including headers or structs defined within a containing struct, can certainly be achieved by writing as many separate assignment statements as needed to assign them all. I believe the syntax that Vladimir proposed for such a "initialize everything to 0" operation was:
header_or_struct = { };
For all 'leaf fields', no matter how deeply embedded, that are bit<W> or int<W> type, they would be initialized with 0. varbit<W> fields would be initialized to 0 length. bool fields would be initialized to false.
error or enum field intialization is TBD. Perhaps the compiler would not allow such initialization for such structs and give an error. Also TBD if a struct contains a header stack or header union member.
Thanks a lot, @jafingerhut !
I hope this construct will promote using local metadata as much as possible, as opposed to the current model, where everything is global, partially due to the convenience of the global metadata being initialized by the architecture.
This is addressed partially by #717
How about using 'false' to initialize an invalid header? So assigning the value 'false' to a header would be the same as 'setInvalid()' The benefit is that you can now initialize a struct containing a header too.
Could we allow assigning true
and false
with the following interpretation? Assigning a bool
to a header sets its validity bit...
I thought, we discussed an option of distinguishing between:
header_t hdr1 = {}; // same as hdr1.setInvalid();
and
header_t hdr1 = { ... }; // Same as hdr1.setValid(); for f in hdr1.fields: hdr.f = ... ;
We have discussed, but I don't think we have agreed. {} is a legal initializer for an empty header, so in that case it's ambiguous - is it valid or invalid?
We can agree that if someone wants to make an empty header valid, they should use {...}
like on any other non-empty ones. Then {}
will always mean invalid.
@vgurevich IMHO, special cases like this are generally a bad idea in language design.
Also, this would be a breaking change in the current definition. Maybe no one cares about this corner case, but it's still a breaking change.
@jnfoster -- I am not sure that this will be a special case. {...}
will have the same semantics for all headers and {}
will have the same semantics for all headers. Same way, we can agree that we are going to initialize structs only with {...}
and not with {}
(even if the struct is empty), and then it will be quite clean.
@mbudiu-vmw -- yes, I agree, this is going to alter the corner case, so we should weigh the pros and cons. I feel that in this case the pros outweigh the cons, but I might be wrong. One way to decide is to check how many programs in use today use both empty headers (or structs), paired with this specific initialization construct.
struct S {
H h;
H h1;
}
S h = { false, { ... } };
Overloading false
to mean "invalid" seems a little confusing to me. It might be cleaner to have a keyword that means invalid.
The keyword needs to be an expression.
How about adding a new 'invalid' literal that means "invalid header"?
!
as a primary expression could mean "invalid".
I forgot about this issue, and created this related one, specifically on the question of a literal syntax for an invalid header: https://github.com/p4lang/p4-spec/issues/1021
Note that because both headers and structs with 0 fields are legal in P4, the open source p4c compiler today treats {}
as a valid header with 0 fields. We could change this, perhaps, but it does seem like an odd thing to do given that {}
has a consistent pattern in explaining why it is valid with expressions like {field1=5}
being a valid header with one field named field1
.
Have we done this now? Can we close it?
It looks done to me. Missing some links in the description, though.