What's wrong
CppGeneratorOptions.MemberNaming defaults to CppMemberNaming.SnakeCase (Schema.Cpp/CppGeneratorOptions.cs:132). CppNaming.Member (Schema.Cpp/CppNaming.cs:26) runs every member, function and parameter name through SnakeCase (CppNaming.cs:55-106). That conversion is many-to-one:
PlayerID and PlayerId both become player_id
fooBar and foo_bar both become foo_bar
Validation only rejects names that are exactly equal (Schema/Models/Schema.Validation.cs:95, where ReportDuplicates groups ordinally). The same holds for function names and parameter names (Schema.Validation.cs around lines 620 and 641). Nothing checks whether two spelled names collide: neither validation nor CppFileBuilder (around lines 222, 240 and 252) does. The generator therefore writes two declarations with the same name.
Failure scenario
Verified with the published ktsu.Schema.Cpp 1.36.11 and g++.
Take a class Player with members PlayerID: Int and PlayerId: Long. Schema.Validate() reports nothing about the names, and CppCodeGenerator.Generate emits:
struct Player
{
std::int32_t player_id{};
std::int64_t player_id{};
};
g++ -std=c++20 then fails with error: redeclaration of 'int64_t game::Player::player_id'.
The C# output for the same schema compiles, so the error appears only in the C++ consumer, and it points at generated code. The reflection table from CppReflectionBuilder (around line 202) names the field the same way, so it is ambiguous as well.
Suggested fix / acceptance criteria
Related, but distinct:
What's wrong
CppGeneratorOptions.MemberNamingdefaults toCppMemberNaming.SnakeCase(Schema.Cpp/CppGeneratorOptions.cs:132).CppNaming.Member(Schema.Cpp/CppNaming.cs:26) runs every member, function and parameter name throughSnakeCase(CppNaming.cs:55-106). That conversion is many-to-one:PlayerIDandPlayerIdboth becomeplayer_idfooBarandfoo_barboth becomefoo_barValidation only rejects names that are exactly equal (
Schema/Models/Schema.Validation.cs:95, whereReportDuplicatesgroups ordinally). The same holds for function names and parameter names (Schema.Validation.csaround lines 620 and 641). Nothing checks whether two spelled names collide: neither validation norCppFileBuilder(around lines 222, 240 and 252) does. The generator therefore writes two declarations with the same name.Failure scenario
Verified with the published ktsu.Schema.Cpp 1.36.11 and g++.
Take a class
Playerwith membersPlayerID: IntandPlayerId: Long.Schema.Validate()reports nothing about the names, andCppCodeGenerator.Generateemits:g++ -std=c++20then fails witherror: redeclaration of 'int64_t game::Player::player_id'.The C# output for the same schema compiles, so the error appears only in the C++ consumer, and it points at generated code. The reflection table from
CppReflectionBuilder(around line 202) names the field the same way, so it is ambiguous as well.Suggested fix / acceptance criteria
CppGenerationException/TargetCannotExpressnaming both schema names and the shared spelling. Apply the same check to interface functions and to the parameters of one function.PlayerID/PlayerIdand another withfooBar/foo_bar. Each should be refused with a clear message rather than producing a header that does not compile.Related, but distinct:
System(CS0426 on System.Numerics/Collections), or when a member shares its class's name (CS0542) #232 covers a member sharing its class's name.