Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Visual Studio 2017 fully support N4266 with the [[deprecated]] attribute?

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.

like image 728
Brotcrunsher Avatar asked Oct 17 '22 04:10

Brotcrunsher


1 Answers

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:

  • Visual C++: No warning on temporary and unused [[deprecated]] variables

The 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.

  • Edit: added a note about this, and it has since been corrected.

Some ambiguity in the official MVSC documentation

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

like image 69
dfrib Avatar answered Oct 30 '22 20:10

dfrib