@@ -2163,8 +2163,8 @@ target-specific).
2163
2163
It is also possible to specify an `enum` with an underlying representation.
2164
2164
These are sometimes called serializable `enum`s, because headers are
2165
2165
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
2168
2168
declaration
2169
2169
2170
2170
~ Begin P4Example
@@ -2189,7 +2189,7 @@ an `enum` with an underlying type can be thought of as being a type derived
2189
2189
from the underlying type carrying equality, assignment, and casts to/from the
2190
2190
underlying type.
2191
2191
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
2193
2193
for an enumeration entry falls outside the representation range of the underlying
2194
2194
type.
2195
2195
@@ -3046,6 +3046,61 @@ casts `a`, which was initialized to `E.e2` to a `bit<8>`, using the specified
3046
3046
fixed-width unsigned integer representation for `E.e2`, `1`. The variable `b` is then set to the
3047
3047
symbolic value `E.e2`, which corresponds to the fixed-width unsigned integer value `1`.
3048
3048
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
+
3049
3104
Note that while it is always safe to cast from an `enum` to its fixed-width unsigned integer type,
3050
3105
and vice versa, there may be cases where casting a fixed-width unsigned integer value to
3051
3106
its related `enum` type produces an unnamed value.
@@ -3056,7 +3111,7 @@ E e = (E) x; // sets e to an unnamed value
3056
3111
~ End P4Example
3057
3112
3058
3113
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`.
3060
3115
3061
3116
For example, in the following code, the `else` clause of the `if/else if/else`
3062
3117
block can be reached even though the matches on `x` are complete with respect
0 commit comments