Skip to content

Joseph Mansfield

Marking as deprecated in C++14

It is common for entities in source code (functions, classes, etc.) to become obsolete or unsafe as a project undergoes development. It's usually a bad idea to remove those entities without any warning, as it'll break any code that interfaces with those entities. Instead, a good practice is to mark them as deprecated in an attempt to discourage their use.

The upcoming C++ release, C++14, introduces the deprecated attribute for specifying that an entity is deprecated. The compiler can then emit warnings whenever these entities are being used. In general, attributes are given as a comma-separated list in double square brackets and can be used in various locations. For example, we can deprecate a function by placing the deprecated attribute at the very beginning of the function declaration:

[[deprecated]]
void foo() {}

int main() {
	foo(); // we're using a deprecated function
}

Compiled with the latest build of clang, this gives the following warning:

warning: 'foo' is deprecated [-Wdeprecated-declarations]
        foo();
        ^
note: 'foo' has been explicitly marked deprecated here
void foo() {}
     ^

It is also possible to supply a message that may inform the users of the deprecated entity. This message must be given as a string literal in parentheses:

[[deprecated("use bar instead")]]
void foo() {}

This gives the following warning instead:

warning: 'foo' is deprecated: use bar instead [-Wdeprecated-declarations]
        foo();
        ^
note: 'foo' has been explicitly marked deprecated here
void foo() {}
     ^

The deprecated attribute can also be applied to classes, typedefs, variables, non-static data members, enumerations, and template specializations. Here's a bunch of examples:

// Deprecate a function
[[deprecated]]
void foo();

// Deprecate a variable
[[deprecated]]
int x;

// Deprecate one declarator in a multi-declarator declaration
int y [[deprecated]], z;

// Deprecate a function parameter
int triple([[deprecated]] int x);

// Deprecate a class (or struct)
class [[deprecated]] my_class {
	public:
		// Deprecate a member
		[[deprecated]] int member;
};

// Deprecate an enum
enum [[deprecated]] animals {
	CAT, DOG, MOUSE
};

// Deprecate a typedef
[[deprecated]]
typedef int type;

// Deprecate a template specialization
template <typename T> class templ;

template <>
class [[deprecated]] templ<int> {};

For those who are curious about the seemingly inconsistent placement of attributes, such as them appearing after the class and enum keywords, it is to distinguish between the deprecation of such a type and the deprecation of a variable of that type. For example, the following deprecates the variable c and not the class itself:

[[deprecated]] class C { } c;

The deprecated attribute need only appear on a single declaration of a particular name or entity in order to mark it as deprecated. That is, later redeclaring without the attribute does not “undeprecate” the declaration. Placing the attribute in a header file declaration will ensure that it appears deprecated to all users of this header file.

The deprecated attribute is supported by Clang 3.4 and GCC 4.9.