ยง7.1.6.3 / 1 (C ++ 14) does not accept the construction in the second fragment below. Why is this?

The first part :

For several days I have been studying some of the details of opaque-enum declarations and specifiers of a specified type, and I really would like someone to confirm this. GCC and VS2013 do not compile this code (clang does), and I believe that clang complies with ยง7.1.6.3 / 1, since enum E is a specified type specifier that is not the only part of the declaration enum E e = E::b; . Is my analysis correct?

 #include <iostream> enum class E : char {a = 'a', b}; int E; enum E e = E::b; // Doesn't compile in GCC and VS2013 int main() { std::cout << (char)(e) << '\n'; } 

Second part:

The snippet below, which is very similar to the one above, does not compile. I understand why this is not so (the specified enum E specifier type is the only component of the enum E; declaration enum E; and ยง7.1.6.3 / 1 does not allow this). What would I like to know why the compiler cannot accept this construct?

 #include <iostream> enum class E : char {a = 'a', b}; int E; enum E; // This doesn't compile. E e = E::b; int main() { std::cout << (char)(e) << '\n'; } 
+5
source share
1 answer

N4140 [basic.scope.hiding] / 2:

The class name (9.1) or enumeration name (7.2) can be hidden by the variable name, data member, function or enumerator declared in the same scope. If a class or enumeration name and a variable, the data member, function, or enumerator are declared in the same scope (in any order) with the same name, the class or enumeration name is hidden wherever the variable, data member, function, or counter name is visible.

It would seem that the declaration of int E hides the name of the enumeration E in the global area after the int the declaration point. However, the name E::b is an identifier with an identifier-nested name E:: , therefore rules are applied to search for a qualified name. In particular, [basic.lookup.qual] / 1:

The name of a member of a class or namespace or enumerator can be passed after resolving the scope :: operator (5.1), applied to the nested qualifier name, which designates its class, namespace or enumeration. If a :: not preceded by a decltype-specifier, the scope operator in the nested qualifier name, searches for the name that precedes :: only considers namespaces, types, and templates whose specialization is types. [emphasized by me]. If the name found does not indicate a namespace or class, enumeration or dependent type, the program is poorly formed.

So clang matches, GCC and MSVC don't.

+7
source

Source: https://habr.com/ru/post/1215792/


All Articles