Is it possible to mark an enum value as deprecated?
e.g.
enum MyEnum {
firstvalue = 0
secondvalue,
thirdvalue, // deprecated
fourthva
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
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
You can use the [[deprecated]] attribute from C++14 on.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3760.html
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.
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".
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.