__pragma(已弃用)和_declspec(已弃用)之间的差异

__pragma(已弃用)和_declspec(已弃用)之间的差异,c,windows,pragma,C,Windows,Pragma,要在Visual Studio下的C/C++中将对象声明为已弃用对象,有三种解决方案: #pragma已弃用(X) \uuu pragma(已弃用(X)) \uu declspec(不推荐使用的(X)) 前两个相同,只是在宏中只能使用第二个;我放第一个只是为了完整。第三个似乎是dev社区中使用最多的 我不知道最后两个有什么区别。根据MSDN和的文档,我理解没有区别。在这种情况下,奇怪的是,根据您使用的是什么,会产生不同的警告代码:对于pragma情况,是C4995;对于declspec情况,

要在Visual Studio下的C/C++中将对象声明为已弃用对象,有三种解决方案:

  • #pragma已弃用(X)
  • \uuu pragma(已弃用(X))
  • \uu declspec(不推荐使用的(X))
前两个相同,只是在宏中只能使用第二个;我放第一个只是为了完整。第三个似乎是dev社区中使用最多的

我不知道最后两个有什么区别。根据MSDN和的文档,我理解没有区别。在这种情况下,奇怪的是,根据您使用的是什么,会产生不同的警告代码:对于pragma情况,是C4995;对于declspec情况,是C4996

那么,是否有人知道实际上是否存在差异(任何微小的差异),或者为什么这些指令不会发出相同的警告代码?

请参阅:

(特定于Microsoft)除了下面提到的例外情况,不推荐的声明提供了与不推荐的杂注相同的功能:

  • deprecated声明允许您将特定形式的函数重载指定为deprecated,而pragma形式适用于函数名的所有重载形式
  • 弃用的声明允许您指定将在编译时显示的消息。消息的文本可以来自宏
  • 宏只能用不推荐的pragma标记为不推荐的

有关
#pragma
u pragma
的对比,请参阅:

__pragma()关键字

特定于Microsoft的

编译器还支持u pragma关键字,该关键字的功能与#pragma指令相同,但可以在宏定义中内联使用


请注意,@Deduplicator提到,C++14引入了
[[deprecated]]]
属性

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

属性标记
已弃用
可用于标记名称和实体,这些名称和实体仍允许使用,但不允许使用 由于某种原因而气馁。[注意:特别是,
已弃用的
适用于 被视为过时或不安全。-结束注释]


还有一件事我刚发现

我在头文件中定义了此类:

class X
{
   void F1();
   void F2();
}
现在,我想弃用F1,但当您使用
pragma deprecated
时,每次包含头文件时,我都会收到警告,即使从未使用过F1

class X
{
#pragma deprecated(F1)
   void F1();
   void F2();
}
现在将其更改为使用
\uu declspec(deprecated())
,您只会在使用F1的时间和确切位置收到deprecated消息。在我看来,除非你想让人们使用
#pragma warning(disable:4995)
,否则你永远不应该使用
#pragma deprecated
,因为有你无法摆脱的警告是非常讨厌的

class X
{
   __declspec(deprecated("Please use F2")) void F1();
   void F2();
}
请注意,
\u declspec(已弃用)
不适用于使用声明的
,而
[[deprecated]]
则适用

  • 非工作:
  • 工作:

是的,我只是看看这一点。事实上,只有declspec解决方案允许在编译过程中使用自定义消息。#pragma在大型项目上的扩展性很差,因为它没有附加到您想要弃用的特定函数上。意外匹配是一种风险,特别是在C++命名空间中。没有这样的问题,这应该是你的喜好。它符合汉斯·帕桑的评论;毫无疑问,
\uu declspec(deprecated())
在所有情况下都应该是首选,但不推荐使用宏的情况除外。谢谢你为C++指出了这个事实。