[[deprecated]] attribute

Document: ISO/IEC JTC1 SC22 WG21 N3760

Date: 2013-09-01

Alberto Ganesh Barbati, <ganesh at barbati dot net>

This is an update of N3394, bearing changes proposed in the pre-Chicago Drafting Review Teleconference of 2013-08-26. The main difference is that the list of the cases where the attribute can be used has changed, by removing namespaces, enumerators, templates and adding non-static data members.

Motivation

Several existing implementations provide ways to annotate entities whose use is discouraged. The goal is achieved using an implementation-specific decoration syntax. For example:

Compiler Simple deprecation Deprecation with message
gcc and clang __attribute__((deprecated)) int a;
__attribute__((deprecated("message"))) int a;
Visual Studio __declspec(deprecated) int a; __declspec(deprecated("message")) int a;
Embarcadero (1)
int a [[deprecated]]; int a [[deprecated("message")]];

(1) Embarcadero currently implements the pre-N3067 C++0x attribute syntax.

Despite the different syntaxes, the behavior is quite consistent in all the above mentioned compilers:

  1. if an entity declared as deprecated is used in the program, the compiler emits a diagnostic message;
  2. if the "deprecation with message" syntax is used, the diagnostic message includes the text provided as the attribute argument;
  3. the diagnostic message is considered by default a "warning" and usual compiler-specific settings can be used to either disable the message or escalate it to an error message.

Given that:

  1. User experience with this annotation has proven it to be useful;
  2. C++11 introduces a standard syntax for attributes, whose aim is precisely to overcome the limitations of implementation-specific annotation syntaxes;
  3. This annotation fits in the guidelines for new attributes described in paper N2761 and is indeed mentioned there as a good candidate;
  4. This annotation has no actual effect beside providing diagnostic messages; as such it provides no implementation challenge as it might be simply ignored without affecting the semantic of a conformant program.

It is hereby proposed to add a new attribute to standardize the existing practice and provide a syntax that is portable among all C++11 implementations.

Discussion

The name deprecated has been chosen because it is already used by the four mentioned implementations and possibly many more. The meaning of the term appears to be well-understood by the end users. Nonetheless, strong objections were raised on the c++-ext reflector because the term "deprecated" appears to be normatively used in the Standard in annex D, para 2 with the following definition:

"Normative for the current edition of the Standard, but not guaranteed to be part of the Standard in future revisions."

This definition is not seen to match with what the proposed deprecated attribute is supposed to mean. As a counter-objection it has been noted that the definition above is actually void of any meaning, because it may be applied to any normative statement in the standard. Moreover the definition doesn't capture the intent of Annex D, that is to present features that have been deliberately selected for a possible future removal and are retained uniquely for backward compatibility purposes. This paper addresses this issue by suggesting a different definition of the term "deprecated". This suggestion is expected to be slightly controversial and it is inessential to the introduction of the deprecated attribute, so it could probably be treated as a separate issue. However, it might still be beneficial to handle both issues in the same paper, to address the objections about the choice of the name deprecated and because both issues are related to the same key paragraph.

On the c++-ext reflector, there was also a discussion about requiring mandatory diagnostic messages rather than "warnings". This paper doesn't propose mandatory diagnostic for the following reasons:

  1. the mere idea has encountered strong opposition on the reflector with several "over my dead body" objections;
  2. it would be an innovation and not the standardization of existing practice: people that are happy with their tools would be discouraged from using the new syntax if that would change the way they work, making the standardization effort pointless;
  3. as mentioned above, most implementation already provide implementation-specific ways to escalate these "warning" messages to "error" messages; having the user rely on them seems a better option;
  4. mandatory diagnostics would require the specification of a complete set of rules for when a deprecated entity is "used"; this effort would likely outweigh the benefit of specifying the feature, which lies in an area ripe for different implementations to compete on QoI.

Acknowledgements

Thanks to Alisdair Meredith for reviewing the paper and for his help in improving the wording. Thanks to William M. Miller for his support during the drafting process and for the proposed definition of the term "deprecated" (which has already been included in N3691, so it has been removed from this paper).

Proposed changes

The wording proposed in this section is based on the latest draft, paper N3691.

Add a new subsection in 7.6 Attributes [dcl.attr]:

Deprecated attribute [dcl.attr.deprecated]

The attribute-token deprecated can be used to mark names and entities whose use is still allowed, but is discouraged for some reason. [Note: in particular, deprecated is appropriate for names and entities that are deemed obsolescent or unsafe. —end note] It shall appear at most once in each attribute-list. An attribute-argument-clause may be present and, if present, it shall have the form:

    ( string-literal )

[Note: the string-literal in the attribute-argument-clause could be used to explain the rationale for deprecation and/or to suggest a replacing entity. —end note]

The attribute may be applied to the declaration of a class, a typedef-name, a variable, a non-static data member, a function, an enumeration, or a template specialization.

A name or entity declared without the deprecated attribute can later be re-declared with the attribute and vice-versa. [Note: Thus, an entity initially declared without the attribute can be marked as deprecated by a subsequent redeclaration. However, after an entity is marked as deprecated, later redeclarations do not un-deprecate the entity. —end note]  Redeclarations using different forms of the attribute (with or without the attribute-argument-clause or with different attribute-argument-clauses) are allowed.

[Note: Implementations may use the deprecated attribute to produce a diagnostic message in case the program refers to a name or entity other than to declare it, after a declaration that specifies the attribute. The diagnostic message may include the text provided within the attribute-argument-clause of any deprecated attribute applied to the name or entity. —end note]

Change Annex D [depr], paragraph 2:

These are deprecated features, where deprecated is defined as: Normative for the current edition of the Standard, but having been identified as a candidate for removal from future revisions. An implementation may declare library names and entities described in this section with the deprecated attribute ([dcl.attr.deprecated]).