You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
What language does this apply to?
C++ generated code.
Describe the problem you are trying to solve.
For a proto field definition:
string foo = 1;
Or:
bytes foo = 1;
Protobuf generates a C-style adapter:
void set_foo(const char* value);
that is atypical in modern C++ and prone to misuse. Internally, this method calls:
set_foo(value, std::strlen(value));
Which the caller could use directly, if desired.
Almost all C++ string types are buffer+length. Many of them support binary data. If components are needed, the appropriate method is
void set_foo(const char* value, int size);
Particularly when the proto declaration is bytes and not string (indicating binary data), it seems likely that std::strlen is not intended.
Describe the solution you'd like
Introduce an:
option features.(pb.cpp).generate_c_string_setter = false
Or features:
option features.(pb.cpp).generate_string_c_string_setter = false
option features.(pb.cpp).generate_bytes_c_string_setter = false
That controls whether such methods are generated.
Then, in a future edition, default it to false either for bytes or for both bytes and strings.
Protobuf should have a mode for modern C++ that disables all the C compatible stuff by default.
Describe alternatives you've considered
There seems to be a small tie-in to language edition. C string setters seem more reasonable in C89 / C++03 than in C23 / C++20. I considered suggesting that the default could vary by language-mode in some way - e.g. if generating C++20 headers, it could be excluded, if generating C++03 headers, it could be included - but that didn't seem clean.
Additional context
In my case, this signature caused an inadvertent truncation issue.
void func(protoType* obj, const char* binaryData, size_t length) {
ATL::CStringA str(binaryData, length);
obj->set_foo(str);
}
String classes (like ATL::CStringT) should probably avoid implicit conversions too, but it's the same issue both ways. ATL::CStringT is trying too hard to be C-compatible by including an implicit conversion, and protobuf is trying to be too hard to be C compatible by including C-string compatible method signatures.
The text was updated successfully, but these errors were encountered:
What language does this apply to?
C++ generated code.
Describe the problem you are trying to solve.
For a proto field definition:
string foo = 1;
Or:
bytes foo = 1;
Protobuf generates a C-style adapter:
void set_foo(const char* value);
that is atypical in modern C++ and prone to misuse. Internally, this method calls:
set_foo(value, std::strlen(value));
Which the caller could use directly, if desired.
Almost all C++ string types are buffer+length. Many of them support binary data. If components are needed, the appropriate method is
void set_foo(const char* value, int size);
Particularly when the proto declaration is bytes and not string (indicating binary data), it seems likely that std::strlen is not intended.
Describe the solution you'd like
Introduce an:
option features.(pb.cpp).generate_c_string_setter = false
Or features:
option features.(pb.cpp).generate_string_c_string_setter = false
option features.(pb.cpp).generate_bytes_c_string_setter = false
That controls whether such methods are generated.
Then, in a future edition, default it to false either for bytes or for both bytes and strings.
Protobuf should have a mode for modern C++ that disables all the C compatible stuff by default.
Describe alternatives you've considered
There seems to be a small tie-in to language edition. C string setters seem more reasonable in C89 / C++03 than in C23 / C++20. I considered suggesting that the default could vary by language-mode in some way - e.g. if generating C++20 headers, it could be excluded, if generating C++03 headers, it could be included - but that didn't seem clean.
Additional context
In my case, this signature caused an inadvertent truncation issue.
void func(protoType* obj, const char* binaryData, size_t length) {
ATL::CStringA str(binaryData, length);
obj->set_foo(str);
}
String classes (like ATL::CStringT) should probably avoid implicit conversions too, but it's the same issue both ways. ATL::CStringT is trying too hard to be C-compatible by including an implicit conversion, and protobuf is trying to be too hard to be C compatible by including C-string compatible method signatures.
The text was updated successfully, but these errors were encountered: