I'm currently investigating the new features of C++17. I stumbled upon the feature N4266, which states that now enums and namespaces can also use attributes. Different sources say that Visual Studio 2017 already fully supports this feature. I wrote a test with the [[deprecated]] attribute. For namespaces, this works very well. However, no warning is generated for enums. Is there a mistake in my implementation? Did I miss something?
enum MyEnum
{
val = 0,
vaal[[deprecated]] = val
};
void test()
{
MyEnum e = MyEnum::vaal; //Should emit Warning, but does not
MyEnum e2 = MyEnum::val; //No Warning
}
I am using Visual Studio Community 2017 Version 15.3.5. This states that it should be supported since VS2015 already. /std:c++17 is used.
And this also says that this should be the correct syntax.
There is no difference if I use enum or enum class.
No, not entirely.
I would say this is a current limitation/bug in MSVC2017 that is possibly worth filing a bug report for, even if the attribute is recognised also in the enumerator case (and doesn't prompt a C5030 warning; as mentioned by Mark in the comments to you question).
Addendum: which has now been verified (as a previously known bug) by a link supplied by Hans Passant:
[[deprecated]]
variablesThe C++17 (working draft) standard, [decl.attr.deprecated], states:
§1 The attribute-token
deprecated
can be used to mark names and entities whose use is still allowed, but is discouraged for some reason.§3 The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data member, a function, a namespace, an enumeration, an enumerator, or a template specialization. ...
Using the /std:c++17
flag when compiling with MSVC2017, the deprecated
attribute works for all the above but the enumerator:
// a class
class [[deprecated]] MyClass {};
// a typedef-name / type alias
[[deprecated]] typedef int MyInt;
using MyFloat [[deprecated]] = float;
// a variable (see main)
// a non-static data member
struct DataMember
{
int b [[deprecated]];
};
// a function
[[deprecated]]
void myFunction() {}
// a namespace
namespace [[deprecated]] my_namespace
{
typedef double MyDouble;
}
// an enumeration
enum [[deprecated]] MyEnum {};
// an enumeration
enum MyNewEnum
{
val[[deprecated]] = 42
};
// a template specialization
template <typename T>
void myTemplateFunction(const T) {}
template<>
[[deprecated]]
void myTemplateFunction<int>(const int) {}
int main()
{
MyClass m; // warning C4996: 'MyClass': was declared deprecated
MyInt i; // warning C4996: 'MyInt': was declared deprecated
MyFloat f; // warning C4996: 'MyInt': was declared deprecated
int j [[deprecated]];
j = 1; // warning C4996: 'j': was declared deprecated
DataMember dm;
dm.b = 1; // warning C4996: 'DataMember::b': was declared deprecated
myFunction();
// warning C4996: 'myFunction': was declared deprecated
my_namespace::MyDouble d;
// warning C4996: 'my_namespace': was declared deprecated
MyEnum e; // warning C4996: 'MyEnum': was declared deprecated
myTemplateFunction(2);
// warning C4996: 'myTemplateFunction': was declared deprecated
MyNewEnum ne = val; // ... no warning
return 0;
}
Both gcc and clang invokes deprecation warnings for MyNewEnum ne = val;
above, for -std=c++14
as well as -std=c++1z
.
On a related note, peculiarly cppreference's description of the deprecated
attribute seems not to have been updated with N4266, not including "an enumerator" and "a namespace" in the valid use case declarations; even though these are both present in the C++14 standard draft (7.6.5/2). This could possibly be an indicator that this is a rarely-used feature (applied to enumerators/namespaces) which could explain why it's been (partly) missed in MVCS.
Finally, the attributes section in the MSVC docs doesn't really dwell any deeper into specifying for which kinds of declarations the deprecated
attribute is allowed; showing only an example of deprecating a function declaration.
Although, as you've pointed out (however via link to cppreference rather than MSVC's own docs), MSVS2015 does explicitly state conformance to N4266, at least for C++17.
Compiler Features
C++17 Core Language Features
N4266 Attributes for namespaces and enumerators
Supported: VS2015
However, Support For C++11/14/17 Features (Modern C++) states the opposite (for VS2015):
Compiler Features
C++17 Proposed Core Language Features
N4266 Attributes for namespaces and enumerators
Supported VS2013: No
Supported VS2015: No
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With