p4-spec icon indicating copy to clipboard operation
p4-spec copied to clipboard

P4_16: Convenient initialization of header/structs

Open jafingerhut opened this issue 7 years ago • 16 comments

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.

jafingerhut avatar Jul 02 '17 17:07 jafingerhut

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.

vgurevich avatar Jul 05 '17 16:07 vgurevich

This is addressed partially by #717

mihaibudiu avatar Apr 22 '19 17:04 mihaibudiu

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.

mihaibudiu avatar Apr 02 '21 22:04 mihaibudiu

Could we allow assigning true and false with the following interpretation? Assigning a bool to a header sets its validity bit...

jnfoster avatar Apr 03 '21 20:04 jnfoster

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 = ... ;

vgurevich avatar Apr 04 '21 20:04 vgurevich

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?

mihaibudiu avatar Apr 05 '21 16:04 mihaibudiu

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 avatar Apr 05 '21 17:04 vgurevich

@vgurevich IMHO, special cases like this are generally a bad idea in language design.

jnfoster avatar Apr 05 '21 17:04 jnfoster

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.

mihaibudiu avatar Apr 05 '21 17:04 mihaibudiu

@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.

vgurevich avatar Apr 05 '21 19:04 vgurevich

struct S { 
  H h;
  H h1;
}

S h = { false, { ... } };

mihaibudiu avatar Apr 05 '21 21:04 mihaibudiu

Overloading false to mean "invalid" seems a little confusing to me. It might be cleaner to have a keyword that means invalid.

blp avatar Apr 05 '21 21:04 blp

The keyword needs to be an expression.

mihaibudiu avatar Apr 05 '21 21:04 mihaibudiu

How about adding a new 'invalid' literal that means "invalid header"?

mihaibudiu avatar Apr 05 '21 21:04 mihaibudiu

! as a primary expression could mean "invalid".

blp avatar Apr 05 '21 21:04 blp

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.

jafingerhut avatar Feb 28 '22 19:02 jafingerhut

Have we done this now? Can we close it?

jnfoster avatar Jul 10 '23 18:07 jnfoster

It looks done to me. Missing some links in the description, though.

mihaibudiu avatar Jul 10 '23 18:07 mihaibudiu