zserio
zserio copied to clipboard
zserio generates one c++ header per constant
I noticed that one header is generated per constant by zserio.
Like: const BoundaryWidth UNKNOWN_BOUNDARY_WIDTH = 0; ends up in lane/boundaries/UNKNOWN_BOUNDARY_WIDTH.h
one header per constant feels somewhat too much (especially if there would be many constant values for the same type).
would it not make more sense to add the constant to the same header that defines type BoundaryWidth?
Please see issue #55. We have faced several issues with constants and splitting them to separate headers was easiest solution which is working across all languages. See also #59.
- There is a problem with constants name clashing. If we put all constants to the header file where the type is defined, how to detect the name clashing - when the constants are defined in different Zserio packages, they can have same name. And what if it's a constant based on a built-in type? I understand that it's not too handy to include all the constants separately, but we wanted to have a generic solution.
- There is also a problem with constants initialization, e.g. when one constant depends on another constant. When putting all the constants in a single header, we would have to sort the constants to define them in a proper order.
Maybe we could add something like constants group. Then it would be possible to define something like:
constants MathConstants
{
const float64 PI = 3.14;
const float64 E = 2.718;
// ...
}
I see the problem, but it makes me think that there are 2 usages of constants:
- constants that are only used in a certain context. For these maybe option 2 is good. Examples are math constants above, constants for ModuleName and ModuleVersion.
- constants that are valid in any context and are an integral part of the type. In this case it is good to reflect the close dependency in zserio, generated code and generated documentation. Example is BoundaryWidth.
For 2, some options:
-
if a constant is in same file, namespace as the type, store them in same c++ header and make the proper references between type and constant in generated documentation.
-
in such cases, define the type as struct and add a function per constant to the struct (no language change required) struct BoundaryWidth { WidthCentimeters value = unknownBoundaryWidth();
function unknownBoundaryWidth() { return 0; } };
-
extend the language to describe type and special values together: subtype WidthCentimeters BoundaryWidth: UNKNOWN_BOUNDARY_WIDTH = 0, HIGH_BOUNDARY_WIDTH = 10000;
Thanks for sharing your ideas.
We think as well that it seems there are two different constants:
- Global Constants - Constants with
const
keyword as we have currently. - Local Constants - Constants defined in the scope of compound type (e.g. structure).
Another example of laguage extension:
struct BoundaryWidth
{
const WidthCentimeters UNKNOWN_BOUNDARY_WIDTH = 0;
const WidthCentimeters HIGH_BOUNDARY_WIDTH = 10000;
};
We should investigate the possibility of namespace approach as well. Example:
namespace Boundaries
{
subtype uint32 BoundaryWidth;
const BoundaryWidth UNKNOWN_BOUNDARY_WIDTH = 0;
const BoundaryWidth HIGH_BOUNDARY_WIDTH = 10000;
};
We should investigate as well the possibility of change of global constant scope. Constants should not have to be visible before definitions:
const uint32 VISIBLE_IN_FOO = 1;
struct Foo
{
};
const uint32 INVISIBLE_IN_FOO = 2;