在Clang中显示弃用的原因

时间:2014-03-02 22:22:54

标签: warnings deprecated clang++ c++14

在C ++ 14中,[[deprecated]]可用于将函数标记为已弃用。他们的工作方式就像你期望的那样;使用标记为deprecated的函数会引发编译器警告。

但是,鉴于您可以添加弃用的原因[[deprecated("reason")]],我最初希望编译器显示弃用的原因。使用clang++ -std=c++1y foo.cpp编译,代码

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

int main(void)
{
  foo();
}

输出

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

没有说明原因。有没有办法让它做到这一点?

我发现通过将属性包含在与函数头相同的行中的唯一方法。我正在寻找的是一个特定的标志,它会给出警告弃用的原因。

代码,

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

int main(void)
{
  foo();
}

产生

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.

这就是我想要的。

2 个答案:

答案 0 :(得分:2)

除了重复之外,

g ++ - 4.9会收到警告消息:

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();
       ^

这是在单独的一行上弃用的。它与在函数名称相同的行上弃用的方式相同。

答案 1 :(得分:1)

N3797 [dcl.attr.deprecated]中描述了不推荐使用的属性。这部分很简短,所以我将其全部包括在内:

  

7.6.5不推荐使用的属性[dcl.attr.deprecated]

     
      
  1. attribute-token deprecated可用于标记仍然允许使用的名称和实体,但由于某种原因不鼓励使用。 [注意:特别是deprecated适用于被视为过时或不安全的名称和实体。 -end note ]每个属性列表中最多只出现一次。可能存在 attribute-argument-clause ,如果存在,则应具有以下形式:

         

    ( string-literal )

         

    [注意: attribute-argument-clause 中的 string-literal 可用于解释弃用的理由和/或建议替换实体。 -end note ]

  2.   
  3. 该属性可以应用于类的声明, typedef-name ,变量,非静态数据成员,函数,枚举或模板特化

  4.   
  5. 稍后可以使用该属性重新声明未声明deprecated属性的名称或实体,反之亦然。 [注意:因此,最初声明没有该属性的实体可以通过后续重新声明标记为已弃用。但是,在将实体标记为已弃用后,稍后的重新声明不会弃用该实体。 -end note ]使用不同形式的属性进行重新声明(使用或不使用 attribute-argument-clause 或使用不同的 attribute-argument-clauses 是允许的。

  6.   
  7. [注意:实现可以使用deprecated属性生成诊断消息,以防程序在声明后引用名称或实体而不是声明它指定属性。诊断消息可以包括应用于名称或实体的任何已弃用属性的 attribute-argument-clause 中提供的文本。 -end note ]

  8.   

请注意,规范性文本指定了deprecated属性的形式和语义用法,但没有说明实现在存在此类属性时应如何操作。无论实现是否报告您正在使用程序中不赞成使用的内容,或者甚至完全忽略这些属性,它在技术上都符合要求。

第4段确实建议实现应诊断对已弃用实体的引用,甚至包括所提供参数的文本,但请记住,注释是非规范性的。符合标准的实现可以忽略deprecated属性,但高质量的实现将诊断引用并包含参数文本。

由于Clang往往是一个高质量的实现,我期望Ali's comment has it right并且Clang的下一个版本将在其诊断中包含属性参数文本。