ETLCPP / etl

Embedded Template Library
https://www.etlcpp.com
MIT License
2.05k stars 372 forks source link

[`string_stream`] Missing initializers for const format specifiers `etl::left` and `etl::right` #848

Closed KnoerleMaTLS closed 2 months ago

KnoerleMaTLS commented 4 months ago

The const variables for the format specifiers etl::left and etl::right which are declared in the file basic_format_spec.h which is used by the file string_stream.h do not have any initializers. Therefore some exotic compilers (e.g. TASKING TriCore) raise an error when including the string_stream.h file with the following error messages:

The error message is already pretty descriptive and explains the requirements which are defined by the C++ standard. Since we are default initializing a const object the following applies: "A class type T is const-default-constructible if default-initialization of T would invoke a user-provided constructor of T" (Source)

All other format specifiers in the namespace private_basic_format_spec do provide a user defined constructor which initializes their member. Since the left_spec and right_spec structs do not have any member they do not provide a constructor, which is the correct solution.

Anyway the standard does not allow to create a const object without initializing it, since it can not be mutated afterwards and therefore will not be in any useful state. But since the struct is empty there is no invalid state.

There is already an open issue about this point of the standard (CWG 253). This issue states the following reported behavior: "default-initialization of a const object could not call an implicitly declared default constructor" The correct behavior would be: "allowed if all subobjects are initialized"

It seems like there are compilers which already implemented their own solution to handle this issue, while there is no official fix of the standard yet. Therefore there were no issues with the GCC or clang compiler when using the string_stream.h file. Anyway the compiler we are using at our project does not accept this.

There are two ways to fix this which came to my mind: 1) Implement an empty user provided default constructor in struct left_spec and struct right_spec (not preferred, rule of zero) 2) Add a copy-initialization to the etl::left and etl::right variables (preferred, valid for all C++ versions)

Further references used to tackle down the problem: https://stackoverflow.com/questions/24943665/why-is-a-constructor-necessary-in-a-const-member-struct https://stackoverflow.com/questions/7411515/why-does-c-require-a-user-provided-default-constructor-to-default-construct-a

jwellbelove commented 2 months ago

Fixed 20.38.11