C++ | Array size of enumeration not reliable in case of not consecutive numbers (actual size does not match)
#15.541 aperta il 23 gen 2024
Metriche repository
- Star
- (71.223 star)
- Metriche merge PR
- (Merge medio 2g 11h) (185 PR mergiate in 30 g)
Descrizione
I have found this issue working on gRPC project, and reported here https://github.com/grpc/grpc/issues/35577. It turns out that is is actually an issue on the underlying protobuf, so I am reporting here.
What version of gRPC and what language are you using?
grpc-1.51.0
What operating system (Linux, Windows,...) and version?
Linux
What runtime / compiler are you using (e.g. python version or version of gcc)
clang-16
What did you do?
Generate C++ code from a pro to containing enumeration (note that 5 is missing)
message Footprint {
int64 id = 1;
enum ConfigType {
UNKNOWN_CONFIG_TYPE = 0;
FP_100 = 1;
FP_250 = 2;
FP_500 = 3;
FP_1000 = 4;
FP_2000 = 6;
}
// Other stuff here
}
What did you expect to see?
Generated code.
/*...*/
enum Footprint_ConfigType : int {
Footprint_ConfigType_UNKNOWN_CONFIG_TYPE = 0,
Footprint_ConfigType_FP_100 = 1,
Footprint_ConfigType_FP_250 = 2,
Footprint_ConfigType_FP_500 = 3,
Footprint_ConfigType_FP_1000 = 4,
Footprint_ConfigType_FP_2000 = 6,
Footprint_ConfigType_Footprint_ConfigType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(),
Footprint_ConfigType_Footprint_ConfigType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max()
};
bool Footprint_ConfigType_IsValid(int value);
constexpr Footprint_ConfigType Footprint_ConfigType_ConfigType_MIN = Footprint_ConfigType_UNKNOWN_CONFIG_TYPE;
constexpr Footprint_ConfigType Footprint_ConfigType_ConfigType_MAX = Footprint_ConfigType_FP_2000;
constexpr int Footprint_ConfigType_ConfigType_ARRAYSIZE = 6;
/*...*/
The Footprint_ConfigType_ConfigType_ARRAYSIZE constant is set to the actual number of items in the enumeration (6 in this case)
What did you see instead?
Generated code:
/*...*/
enum Footprint_ConfigType : int {
Footprint_ConfigType_UNKNOWN_CONFIG_TYPE = 0,
Footprint_ConfigType_FP_100 = 1,
Footprint_ConfigType_FP_250 = 2,
Footprint_ConfigType_FP_500 = 3,
Footprint_ConfigType_FP_1000 = 4,
Footprint_ConfigType_FP_2000 = 6,
Footprint_ConfigType_Footprint_ConfigType_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::min(),
Footprint_ConfigType_Footprint_ConfigType_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<int32_t>::max()
};
bool Footprint_ConfigType_IsValid(int value);
constexpr Footprint_ConfigType Footprint_ConfigType_ConfigType_MIN = Footprint_ConfigType_UNKNOWN_CONFIG_TYPE;
constexpr Footprint_ConfigType Footprint_ConfigType_ConfigType_MAX = Footprint_ConfigType_FP_2000;
constexpr int Footprint_ConfigType_ConfigType_ARRAYSIZE = Footprint_ConfigType_ConfigType_MAX + 1;
/*...*/
The Footprint_ConfigType_ConfigType_ARRAYSIZE constant is set to Footprint_ConfigType_ConfigType_MAX + 1 that become 7 in this case because item 5 is missing. As it is, the Footprint_ConfigType_ConfigType_ARRAYSIZE is not reliable and cannot be used as boundary check in for loops.
Workaround: Need to take a separate counter for the actual number element in the enumeration.
Anything else we should know about your project / environment?
Nothing to add