protocolbuffers / protocolbuffers/protobuf

C++ | Array size of enumeration not reliable in case of not consecutive numbers (actual size does not match)

Open
#15,541 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

c++ help wanted
Dominant language
C++
Stars
72k
Forks
16.3k
Avg merge
1d 17h
Merged PRs (30d)
140

Description

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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Reproduce the generated C++ output from the protobuf enum example, focusing on an enumeration with a missing numeric value such as 5. Trace where the *_ARRAYSIZE constant is produced and verify the result against the expected actual number of enum items; done means non-consecutive values no longer make the constant exceed the item count.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
compilers
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.