The following code compiles just fine on both Clang and MSVC, but fails on GCC.
1 2 3 4 5 6
struct Test {};
struct Foo
{
Test Test;
};
prog.cpp:5:7: error: declaration of 'Test Foo::Test' [-fpermissive]
Test Test;
^
prog.cpp:1:8: error: changes meaning of 'Test' from 'struct Test' [-fpermissive]
struct Test {};
^
Honestly, I think this is stupid as hell. Coming up with meaningful names is hard, and I don't want to have to rule out the clearest one just because there's already a type with that name. I get how it may cause some ambiguity with functions and types that overload the function call operator, but other than that I don't care. I have two questions here:
1) Why does GCC error out on this, while the other compilers don't say anything, even with maximum warning levels enabled?
2) I can bring it down to a warning by using -fpermissive, but from what I can tell that's it. I want to get rid of the warning completely because I think it's stupid. How can I do that (without changing my code, because again: stupid)?
1. Most likely, you're not really enabling maximum warning levels. VC++ is also known to be supremely liberal in what it accepts (I actually just had a case where it allowed a class to be copied despite explicitly deleting the copy constructor. It baffled me but is an extension which allows objects to be constructed using copy constructor syntax while really using the default or explicit constructors).
2. It's going to give you a warning because it's horrid practice, almost agreed upon on a global community level. I can't imagine why you can't just use "Test test" where it's easy to tell the difference simply because of capitalization.
EDIT: I am curious as to what the standard says about it though.
A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S. No diagnostic is required for a violation of this rule.
Prepending with "struct" or "::" fixes cases where the the field and its type share the same name, but not cases where the field shares a name with a different type. What can I do for that?
it's horrid practice, almost agreed upon on a global community level
I don't think so. The official coding style guides for Epic Games, Microsoft, LLVM, and more all suggest using Pascal Case for types and field names, which inevitably leads to collisions (and most languages are totally fine with that, except C++ apparently); though ultimately it comes down to personal preference.
Does that mean the community of "all programmers" or "C++ programmers"?
IMHO unnecessary ambiguity is bad style.
Having a consistent style is good, so a style guide is good, but each point in the guide must have a rationale. MSDN guide, for example, probably targets their C#/.NET.
I'd say all where a variable name could then collide with the variable type.
Although, I wouldn't know. I've seen a few dozen styles, all cringing and usually explicitly disallowing the use of such confusing syntax. Those that don't explicitly disallow it will usually reject it upon review or be criticized later if the code base has no peer review at all and someone runs into it.
I never argued anything against consistent style. If a code base already did this, I would also follow along to be consistent. However, the idea that I'd reference "Test" and I get a compiler error screaming about how it's a type and not an identifier in specific situations is far less than ideal and confusing.
Most people do not use upper camel case variable names because it's confusing.