moala
moala

Reputation: 5334

c++ mark enum value as deprecated?

Is it possible to mark an enum value as deprecated?

e.g.

enum MyEnum {
    firstvalue = 0
    secondvalue,
    thirdvalue, // deprecated
    fourthvalue
};

A second prize solution would be to ifdef a MSVC and a GCC solution.

Upvotes: 34

Views: 9910

Answers (9)

László Papp
László Papp

Reputation: 53173

You can use the [[deprecated]] attribute from C++14 on.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3760.html

So, you would write this:

enum MyEnum {
    firstvalue = 0
    secondvalue,
    thirdvalue [[deprecated]],
    fourthvalue
};

When you deprecate an enum value with value explicitly assigned, then it would look like this:

enum MyEnum {
    firstvalue = 0
    secondvalue,
    thirdvalue [[deprecated]] = 2,
    fourthvalue
};

Upvotes: 22

user2023370
user2023370

Reputation: 11037

C++14's support for a standard syntax attributes (including [[deprecated]]) improved on that of C++11's by allowing enumerators also to be annotated (see N3760). This means the OP's example can now look like this:

enum MyEnum {
  firstvalue = 0,
  secondvalue,
  thirdvalue [[deprecated]],
  fourthvalue
};

Upvotes: 0

usr1234567
usr1234567

Reputation: 23294

Beginning with GCC 6 you can simply deprecate enums:

enum {
  newval,
  oldval __attribute__ ((deprecated ("too old")))
};

Source: https://gcc.gnu.org/gcc-6/changes.html

Upvotes: 8

Emile Cormier
Emile Cormier

Reputation: 29199

I have a solution (inspired from Mark B's) that makes use of boost/serialization/static_warning.hpp. However, mine allows thirdvalue to be used as a symbolic constant. It also produces warnings for each place where someone attempts to use thirdvalue.

#include <boost/serialization/static_warning.hpp>

enum MyEnum {
    firstvalue = 0,
    secondvalue,
    deprecated_thirdvalue, // deprecated
    fourthvalue
};

template <int line>
struct Deprecated
{
    BOOST_SERIALIZATION_BSW(false, line);
    enum {MyEnum_thirdvalue = deprecated_thirdvalue};
};

#define thirdvalue (static_cast<MyEnum>(Deprecated<__LINE__>::MyEnum_thirdvalue))

enum {symbolic_constant = thirdvalue};

int main()
{
    MyEnum e = thirdvalue;
}

On GCC I get warnings that ultimately point to the culprit lines containing thirdvalue.

Note that the use of the Deprecated template makes it so that an "instantiated here" compiler output line shows where the deprecated enum is used.

If you can figure out a way to portably generate a warning inside the Deprecated template, then you can do away with the dependency on Boost.

Upvotes: 0

Tom
Tom

Reputation: 918

you could do this:

enum MyEnum {
    firstvalue = 0,
    secondvalue,
    thirdvalue, // deprecated
    fourthvalue
};
#pragma deprecated(thirdvalue)

then when ever the variable is used, the compiler will output the following:

warning C4995: 'thirdvalue': name was marked as #pragma deprecated

EDIT
This looks a bit hacky and i dont have a GCC compiler to confirm (could someone do that for me?) but it should work:

enum MyEnum {
    firstvalue = 0,
    secondvalue,
#ifdef _MSC_VER
    thirdvalue,
#endif
    fourthvalue = secondvalue + 2
};

#ifdef __GNUC__
__attribute__ ((deprecated)) const MyEnum thirdvalue = MyEnum(secondvalue + 1);
#elif defined _MSC_VER
#pragma deprecated(thirdvalue)
#endif

it's a combination of my answer and MSalters' answer

Upvotes: 14

Damon
Damon

Reputation: 70106

Well, since we're at macro hacks already, here is mine :-)

enum MyEnum
{
 foo,
 bar,
 baz
};

typedef __attribute__ ((deprecated))MyEnum MyEnum_deprecated;
#define bar ((MyEnum_deprecated) bar)

int main ()
{
    int a = foo; // yuck, why did C++ ever allow that...
    int b = bar;

    MyEnum c = foo;
    MyEnum d = bar;

    return 0;
}

This works with gcc, and it does not require you to break type-safety. Unluckily it still abuses your code with macros, so meh. But as far as I could figure, it's as good as it gets.

The proposal made by Tom is much cleaner (works for MSVC, I assume), but unluckily the only message gcc will give you is "ignoring pragma".

Upvotes: 3

MSalters
MSalters

Reputation: 179779

You can declare enum constants outside an enum declaration:

enum MyEnum {
    firstvalue = 0
    secondvalue,
    thirdvalue
};
__attribute__ ((deprecated)) const MyEnum fourthvalue = MyEnum(thirdvalue + 1);

Upvotes: 3

Mark B
Mark B

Reputation: 96233

You might be able to use some macro hackery.

enum MyEnum {
    firstvalue = 0
    secondvalue,
    real_thirdvalue, // deprecated
    fourthvalue
};

template <MyEnum v>
struct real_value
{
    static MyEnum value()
    { 
        1 != 2U;  // Cause a warning in for example g++. Leave a comment behind for the user to translate this warning into "thirdvalue is deprecated"
        return v;
    }
};

#define thirdvalue (real_value<real_thirdvalue>::value());

This won't work in a context when a constant is needed.

Upvotes: 1

Sadique
Sadique

Reputation: 22813

Using compiler dependent pragmas: Here is the documentation for Gcc and Visual Studio.

Upvotes: 1

Related Questions