Warning with repeated enum
What version of protobuf and what language are you using? Version: release 3.20 (pre-built binaries) Language: C++
What operating system (Linux, Windows, ...) and version? Windows 11
What runtime / compiler are you using (e.g., python version or gcc version) VS Studio 2022 / MSVC
What did you do? Steps to reproduce the behavior:
- Use following test.proto file:
syntax = "proto3";
enum foo{
empty = 0;
bar = 1;
baz = 2;
}
message output{
repeated foo myFoo = 1;
}
- Execute protoc:
<PATH>\protoc.exe -I=./ --cpp_out=./ test.proto - Examine output *.pb.cc:
[...] line 280ish:
{
std::size_t byte_size =
this_._impl_._myfoo_cached_byte_size_.Get();
if (byte_size > 0) {
target = stream->WriteEnumPacked(
1, this_._internal_myfoo(), byte_size, target);
}
}
[...]
What did you expect to see No warning in generated code.
What did you see instead?
WriteEnumPacked uses an int as size parameter, but byte_size is type std::size. This produces warning C4267: 'argument': conversion from 'size_t' to 'int', possible loss of data
Anything else we should know about your project / environment
.Get() returns an int, but is casted to std::size_t. If auto would be used for byte_size everything would work.
We triage inactive PRs and issues in order to make it easier to find active work. If this issue should remain active or becomes active again, please add a comment.
This issue is labeled inactive because the last activity was over 90 days ago. This issue will be closed and archived after 14 additional days without activity.
I found this issue and found that protobuf 5.29.5#1 generates a size_t for an enum, but WriteEnumPacked requires an int. On Windows, with Visual Studio 2022, v17.14.14 this casues warning C4267. Hopefully, this information is useful and not stealing an issue from someone else.
In my case, the generated code is:
// repeated .proto.AIModel SupportedModels = 1;
{
std::size_t byte_size =
this_._impl_._supportedmodels_cached_byte_size_.Get();
if (byte_size > 0) {
target = stream->WriteEnumPacked(
1, this_._internal_supportedmodels(), byte_size, target);
}
}
The belonging .proto file is:
message SupportedModelsResponse {
repeated AIModel SupportedModels = 1;
repeated AIVersion CurrentlyAvailableVersions = 2;
}
and
enum AIModel {
x= 0;
y = 1;
z = 2;
}
I think the cause is in combination with the repated keyword. We are using enum in other places, but that occurences do not call WriteEnumPacked.
The solution is that the protoc compiler should not generate size_t for enum. or WriteEnumPacked should accept a size_t. Our builds are x64, so size_t is 8-bytes (similar to Linux 64-bit gcc compilers).
BTW: there are more warnings in the generated protoc code, like:
- C4100: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4100?view=msvc-170, i.e. a method that uses a named parameter, but the parameter at all is not used
- C4127: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-4-c4127?view=msvc-170, a conditional expression is const
- C4267: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-3-c4267?view=msvc-170, as said before
I'm using protobuf/protoc v5.29 in compbination with grpc v1.71.
I also found https://github.com/protocolbuffers/protobuf/issues/23248, which looks quite similar.
Note that an older version (checked with 3.21.12) of protoc compiler generated:
// repeated .proto.AIModel SupportedModels = 1;
{
int byte_size = _impl_._supportedmodels_cached_byte_size_.load(std::memory_order_relaxed);
if (byte_size > 0) {
target = stream->WriteEnumPacked(
1, _impl_.supportedmodels_, byte_size, target);
}
}
As then a int is used for byte_size, no warning is issued.
We would accept a PR for this.