Skip to content

Commit 41dda85

Browse files
Vladimir Gurevichmbudiu-vmw
Vladimir Gurevich
authored and
mbudiu-vmw
committed
Issue #774: Allow automatic conversions from a serializable enum to an underlying type.
* Added the proposed description * Also extended the definition of serializable enum to allow int<w> to be an underlying type too.
1 parent bc50642 commit 41dda85

File tree

1 file changed

+59
-4
lines changed

1 file changed

+59
-4
lines changed

Diff for: p4-16/spec/P4-16-spec.mdk

+59-4
Original file line numberDiff line numberDiff line change
@@ -2163,8 +2163,8 @@ target-specific).
21632163
It is also possible to specify an `enum` with an underlying representation.
21642164
These are sometimes called serializable `enum`s, because headers are
21652165
allowed to have fields with such `enum` types.
2166-
This requires the programmer provide both the fixed-width unsigned integer type and an associated
2167-
fixed-width unsigned integer value for each symbolic entry in the enumeration. For example, the
2166+
This requires the programmer provide both the fixed-width unsigned (or signed) integer type and
2167+
an associated integer value for each symbolic entry in the enumeration. For example, the
21682168
declaration
21692169

21702170
~ Begin P4Example
@@ -2189,7 +2189,7 @@ an `enum` with an underlying type can be thought of as being a type derived
21892189
from the underlying type carrying equality, assignment, and casts to/from the
21902190
underlying type.
21912191

2192-
Compiler implementations are expected to raise an error if the fixed-width unsigned integer representation
2192+
Compiler implementations are expected to raise an error if the fixed-width integer representation
21932193
for an enumeration entry falls outside the representation range of the underlying
21942194
type.
21952195

@@ -3046,6 +3046,61 @@ casts `a`, which was initialized to `E.e2` to a `bit<8>`, using the specified
30463046
fixed-width unsigned integer representation for `E.e2`, `1`. The variable `b` is then set to the
30473047
symbolic value `E.e2`, which corresponds to the fixed-width unsigned integer value `1`.
30483048

3049+
Because it is always safe to cast from an `enum` to its underlying fixed-width integer type,
3050+
automatic casting from an `enum` to its fixed-width (signed or unsigned) integer type is also supported:
3051+
3052+
~ Begin P4Example
3053+
bit<8> x = E.e2; // sets x to 1 (E.e2 is automatically casted to bit<8>)
3054+
3055+
E a = E.e2
3056+
bit<8> y = a << 3; // sets y to 8 (a is automatically casted to bit<8> and then shifted)
3057+
~ End P4Example
3058+
3059+
Automatic casting from an underlying fixed-width type to an enum is *not* supported.
3060+
3061+
~ Begin P4Example
3062+
enum bit<8> E1 {
3063+
e1 = 0, e2 = 1, e3 = 2
3064+
}
3065+
3066+
enum bit<8> E1 {
3067+
e1 = 10, e2 = 11, e3 = 12
3068+
}
3069+
E1 a = E1.e1;
3070+
E2 b = E2.e2;
3071+
3072+
a = b; // Error: b is automatically casted to bit<8>,
3073+
// but bit<8> cannot be automatically casted to E1
3074+
3075+
a = (E1) b; // OK
3076+
3077+
a = E1.e1 + 1; // Error: E.e1 is automatically casted to bit<8>,
3078+
// and the right-hand expression has
3079+
// the type bit<8>, which cannot be casted to E automatically.
3080+
3081+
a = (E1)(E1.e1 + 1); // Final explicit casting makes the assinment legal
3082+
3083+
a = E1.e1 + E1.e2; // Error: both arguments to the addition are automatically
3084+
// casted to bit<8>. Thus the addition itself is legal, but
3085+
// the assignment is not
3086+
3087+
a = (E)(E.e1 + E.e2); // Final explicit casting makes the assinment legal
3088+
~ End P4Example
3089+
3090+
A reasonable compiler might generate a warning in cases that involve multiple automatic casts.
3091+
3092+
~ Begin P4Example
3093+
E1 a = E1.e1;
3094+
E2 b = E2.e2;
3095+
bit<8> c;
3096+
3097+
if (a > b) { // Warning: two automatic and different casts to bit<8>. Otherwise OK
3098+
...
3099+
}
3100+
3101+
c = a + b; // Legal, but a warning would be reasonable
3102+
~ End P4Example
3103+
30493104
Note that while it is always safe to cast from an `enum` to its fixed-width unsigned integer type,
30503105
and vice versa, there may be cases where casting a fixed-width unsigned integer value to
30513106
its related `enum` type produces an unnamed value.
@@ -3056,7 +3111,7 @@ E e = (E) x; // sets e to an unnamed value
30563111
~ End P4Example
30573112

30583113
sets `e` to an unnamed value, since there is no symbol corresponding to the
3059-
fixed-width unsigned integer value `5`.
3114+
fixed-width unsigned integer value `5`.
30603115

30613116
For example, in the following code, the `else` clause of the `if/else if/else`
30623117
block can be reached even though the matches on `x` are complete with respect

0 commit comments

Comments
 (0)