Question

In C++14, [[deprecated]] can be used to mark functions as deprecated. They work just as you expect in clang; using a function marked as deprecated induces a compiler warning.

However, given that you can add a reason for deprecation, [[deprecated("reason")]], I originally expected the compiler to show the reason of deprecation. Compiled with clang++ -std=c++1y foo.cpp, the code,

[[deprecated("Avoid at all cost!")]]
void foo() { }

int main(void)
{
  foo();
}

outputs,

test.cpp:6:3: warning: 'foo' is deprecated [-Wdeprecated-declarations]
  foo();
  ^
test.cpp:2:6: note: 'foo' declared here
void foo() { }
     ^
1 warning generated.

without specifying the reason. Is there a way to get it to do that?

The only way I have found to do that by including the attribute on the same line as the function header. What I'm looking for is a specific flag that would give the reason for deprecation with the warning.

The code,

[[deprecated("Avoid at all cost!")]] void foo() { }

int main(void)
{
  foo();
}

produces,

test.cpp:5:3: warning: 'foo' is deprecated [-Wdeprecated-declarations]
  foo();
  ^
test.cpp:1:43: note: 'foo' declared here
[[deprecated("Avoid at all cost!")]] void foo() { }
                                      ^
1 warning generated.

which is sort of what I want.

Was it helpful?

Solution 2

The deprecated attribute is described in N3797 [dcl.attr.deprecated]. The section is short, so I'll include it entire:

7.6.5 Deprecated attribute [dcl.attr.deprecated]

  1. 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 ]

  2. 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.

  3. 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.

  4. [ 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 ]

Notice that the normative text specifies the form and semantic usage of a deprecated attribute, but says nothing about how implementations should act in the presence of such an attribute. Whether or not an implementation reports that you are using something deprecated in your program or even simply ignores the attributes altogether, it's technically conforming.

Paragraph 4 does suggest that an implementation should diagnose references to a deprecated entity, and even include the text of the provided argument, but remember that notes are non-normative. A conforming implementation can ignore the deprecated attribute, but a high-quality implementation will diagnoses references and include the argument text.

Since Clang tends to be a high-quality implementation, I expect that Ali's comment has it right and that the next release of Clang will include the attribute argument text in its diagnostics.

OTHER TIPS

g++-4.9 gets the warning message except with a duplicate:

ed@bad-horse:~$ ./bin/bin/g++ -std=c++1y foo.cpp 
foo.cpp: In function ‘int main()’:
foo.cpp:6:3: warning: ‘void foo()’ is deprecated (declared at foo.cpp:2): Avoid at all cost! [-Wdeprecated-declarations]
   foo();
   ^
foo.cpp:6:7: warning: ‘void foo()’ is deprecated (declared at foo.cpp:2): Avoid at all cost! [-Wdeprecated-declarations]
   foo();
       ^

This is with the deprecated on a separate line. It works the same way with the deprecated on the same line as the function name.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top