Attributes for namespaces and enumerators (original) (raw)

ISO/IEC JTC1 SC22 WG21
N4196 / CWG 1657 / EWG 113
Richard Smith
richard@metafoo.co.uk
2014-10-06

Motivation

WhenN3394introduced the [[deprecated]] attribute to C++, there was a desire for it to apply to:

However, attributes are not permitted on enumerators nor on namespaces. In response,CWG issue 1657 andEWG issue 113 were filed and received favourably. This paper proposes resolving these issues by allowing attributes to be specified on enumerators and namespaces, and extends the[[deprecated]] attribute to apply to these entities, as was originally intended.

Discussion

Location of attributes on enumerators

Once we decide to allow attributes on enumerators, we must answer one question: are attributes written before or after the name of the enumerator? There are no grammar ambiguities in either location, so this is a free choice. Analysis of the grammar and prior papers results in a simple rule: attributes are written either

This choice also preserves the ability to lay out enumerations with the enumerator names in a column.

Attributes on namespaces

Namespaces can be repeatedly declared and can be reopened, and thus can have different attributes in different translation units or in different locations in the same translation unit. Likewise, namespaces can be anonymous or inline, and some namespace attributes might be problematic in such cases. Nonetheless, this paper proposes allowing attributes in all such cases, with no inherent restrictions; the specification for each individual attribute that can appertain to a namespace should cover how to handle any problematic cases. This is the status quo for attributes on other entities.

For consistency with classes and enumerations, the natural location for the_attribute-specifier-seq_ is after the namespace keyword.

Meaning of deprecating a namespace

Following the lead of N3394, this paper provides no normative requirements on the effect of deprecating an entity. For an inline namespace, this paper suggests that implementations might wish to consider issuing a warning only if the name of the namespace is used (and not if entities within that namespace are named as members of a surrounding namespace). This allows a library author to discourage its clients from naming an inline namespace directly, while still allowing access to its members. With this approach, deprecating an unnamed namespace would have no effect, and implementations may wish to issue a warning on such a construct.

Proposed Wording

Change in 7.2 (dcl.enum) paragraph 1:

[...]

enumerator: identifier attribute-specifier-seqopt

The optional attribute-specifier-seq in the enum-head and the opaque-enum-declaration appertains to the enumeration; the attributes in that attribute-specifier-seq are thereafter considered attributes of the enumeration whenever it is named. [...]

Change in 7.2 (dcl.enum) paragraph 2:

[...] The identifiers in an_enumerator-list_ are declared as constants, and can appear wherever constants are required. An enumerator-definition with = gives the associated enumerator the value indicated by the constant-expression. If the first enumerator has no initializer, the value of the corresponding constant is zero. An enumerator-definition_without an initializer gives the enumerator the value obtained by increasing the value of the previous_enumerator by one. [ Example: … ]The optional attribute-specifier-seq in an enumerator appertains to that enumerator.

Change in 7.3 (namespace.def) paragraph 1:

[...]

original-namespace-definition: inline_opt_ namespace attribute-specifier-seqopt identifier { namespace-body } extension-namespace-definition: inline_opt_ namespace attribute-specifier-seqopt original-namespace-name { namespace-body } unnamed-namespace-definition: inline_opt_ namespace attribute-specifier-seqopt { namespace-body } namespace-body: declaration-seqopt

Add a new paragraph after 7.3 (namespace.def) paragraph 7:

The optional attribute-specifier-seq in a namespace-definition appertains to the namespace being defined or extended.

Change in 7.6.5 (dcl.attr.deprecated) paragraph 2:

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.