C++ 标记为已弃用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/295120/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
C++ mark as deprecated
提问by Diederik
I have a method in an interface that I want to deprecate with portable C++. When I Googled for this all I got was a Microsoft specific solution; #pragma deprecatedand __declspec(deprecated).
我在一个接口中有一个方法,我想用可移植的 C++ 来弃用它。当我用谷歌搜索这个时,我得到的只是一个微软特定的解决方案;#pragma deprecated和__declspec(deprecated)。
A second prize solution would be to ifdef a MSVC and a GCC solution.
Thanks
二等奖的解决方案是 ifdef 一个 MSVC 和一个 GCC 解决方案。
谢谢
回答by Joseph Mansfield
In C++14, you can mark a function as deprecated using the [[deprecated]]
attribute (see section 7.6.5 [dcl.attr.deprecated]).
在 C++14 中,您可以使用[[deprecated]]
属性将函数标记为已弃用(请参阅第 7.6.5 节 [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.
该属性令牌
deprecated
可以用来标记的名称和它的使用仍然是允许的实体,但不鼓励出于某种原因。
For example, the following function foo
is deprecated:
例如,foo
不推荐使用以下函数:
[[deprecated]]
void foo(int);
It is possible to provide a message that describes why the name or entity was deprecated:
可以提供一条消息来描述名称或实体被弃用的原因:
[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);
The message must be a string literal.
消息必须是字符串文字。
For further details, see “Marking as deprecated in C++14”.
有关更多详细信息,请参阅“在 C++14 中标记为已弃用”。
回答by Michael Platings
This should do the trick:
这应该可以解决问题:
#ifdef __GNUC__
#define DEPRECATED(func) func __attribute__ ((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED(func) __declspec(deprecated) func
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED(func) func
#endif
...
//don't use me any more
DEPRECATED(void OldFunc(int a, float b));
//use me instead
void NewFunc(int a, double b);
However, you will encounter problems if a function return type has a commas in its name e.g. std::pair<int, int>
as this will be interpreted by the preprocesor as passing 2 arguments to the DEPRECATED macro. In that case you would have to typedef the return type.
但是,如果函数返回类型的名称中包含逗号,则会遇到问题,例如std::pair<int, int>
,预处理器会将其解释为将 2 个参数传递给 DEPRECATED 宏。在这种情况下,您必须 typedef 返回类型。
Edit: simpler (but possibly less widely compatible) version here.
编辑:简单(但可能不太广泛兼容)的版本在这里。
回答by Michael Platings
Here's a simplified version of my 2008 answer:
这是我2008 年回答的简化版本:
#if defined(__GNUC__) || defined(__clang__)
#define DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED __declspec(deprecated)
#else
#pragma message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED
#endif
//...
//don't use me any more
DEPRECATED void OldFunc(int a, float b);
//use me instead
void NewFunc(int a, double b);
See also:
也可以看看:
回答by Terje Mikal
In GCC you can declare your function with the attribute deprecated like this:
在 GCC 中,您可以使用已弃用的属性声明您的函数,如下所示:
void myfunc() __attribute__ ((deprecated));
This will trigger a compile-time warning when that function is used in a .c file.
当在 .c 文件中使用该函数时,这将触发编译时警告。
You can find more info under "Diagnostic pragmas" at http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html
您可以在http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html 的“Diagnostic pragmas”下找到更多信息
回答by nemequ
Here is a more complete answer for 2018.
这是2018年更完整的答案。
These days, a lot of tools allow you to not just mark something as deprecated, but also provide a message. This allows you to tell people when something was deprecated, and maybe point them toward a replacement.
如今,许多工具不仅可以让您将某些内容标记为已弃用,还可以提供消息。这使您可以告诉人们什么时候不赞成使用某些东西,并可能将他们指向替代品。
There is still a lot of variety in compiler support:
编译器支持仍然多种多样:
- C++14 supports
[[deprecated]]
/[[deprecated(message)]]
. __attribute__((deprecated))
is supported by GCC 4.0+ and ARM 4.1+__attribute__((deprecated))
and__attribute__((deprecated(message)))
is supported for:- GCC 4.5+
- Several compilers which masquerade as GCC 4.5+ (by setting
__GNUC__
/__GNUC_MINOR__
/__GNUC_PATCHLEVEL__
) - Intel C/C++ Compiler going back to at least 16 (you can't trust
__GNUC__
/__GNUC_MINOR__
, they just set it to whatever version of GCC is installed) - ARM 5.6+
- MSVC supports
__declspec(deprecated)
since 13.10 (Visual Studio 2003) - MSVC supports
__declspec(deprecated(message))
since 14.0 (Visual Studio 2005)
- C++14 支持
[[deprecated]]
/[[deprecated(message)]]
。 __attribute__((deprecated))
GCC 4.0+ 和 ARM 4.1+ 支持__attribute__((deprecated))
并__attribute__((deprecated(message)))
支持:- 海湾合作委员会 4.5+
- 几个编译器,其伪装成GCC 4.5+(由设定
__GNUC__
/__GNUC_MINOR__
/__GNUC_PATCHLEVEL__
) - 英特尔 C/C++ 编译器至少可以追溯到 16(你不能相信
__GNUC__
/__GNUC_MINOR__
,他们只是将它设置为安装的任何版本的 GCC) - ARM 5.6+
__declspec(deprecated)
自 13.10 (Visual Studio 2003) 起支持 MSVC__declspec(deprecated(message))
自 14.0 (Visual Studio 2005) 起支持 MSVC
You can also use [[gnu::deprecated]]
in recent versions of clang in C++11, based on __has_cpp_attribute(gnu::deprecated)
.
您还可以[[gnu::deprecated]]
在 C++11 的最新版本中使用基于__has_cpp_attribute(gnu::deprecated)
.
I have some macros in Hedleyto handle all of this automatically which I keep up to date, but the current version (v2) looks like this:
我在Hedley 中有一些宏可以自动处理所有这些我会保持最新状态,但当前版本 (v2) 如下所示:
#if defined(__cplusplus) && (__cplusplus >= 201402L)
# define HEDLEY_DEPRECATED(since) [[deprecated("Since " #since)]]
# define HEDLEY_DEPRECATED_FOR(since, replacement) [[deprecated("Since " #since "; use " #replacement)]]
#elif \
HEDLEY_GCC_HAS_EXTENSION(attribute_deprecated_with_message,4,5,0) || \
HEDLEY_INTEL_VERSION_CHECK(16,0,0) || \
HEDLEY_ARM_VERSION_CHECK(5,6,0)
# define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since)))
# define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement)))
#elif \
HEDLEY_GCC_HAS_ATTRIBUTE(deprcated,4,0,0) || \
HEDLEY_ARM_VERSION_CHECK(4,1,0)
# define HEDLEY_DEPRECATED(since) __attribute__((__deprecated__))
# define HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__))
#elif HEDLEY_MSVC_VERSION_CHECK(14,0,0)
# define HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since))
# define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement))
#elif HEDLEY_MSVC_VERSION_CHECK(13,10,0)
# define HEDLEY_DEPRECATED(since) _declspec(deprecated)
# define HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated)
#else
# define HEDLEY_DEPRECATED(since)
# define HEDLEY_DEPRECATED_FOR(since, replacement)
#endif
I'll leave it as an exercise to figure out how to get rid of the *_VERSION_CHECK
and *_HAS_ATTRIBUTE
macros if you don't want to use Hedley (I wrote Hedley largely so I wouldn't have to think about that on a regular basis).
如果您不想使用 Hedley,我将把它作为练习来弄清楚如何摆脱*_VERSION_CHECK
和*_HAS_ATTRIBUTE
宏(我主要写了 Hedley,所以我不必定期考虑它)。
If you use GLib, you can use the G_DEPRECATED
and G_DEPRECATED_FOR
macros. They're not as robust as the ones from Hedley, but if you already use GLib there is nothing to add.
如果您使用 GLib,则可以使用G_DEPRECATED
和G_DEPRECATED_FOR
宏。它们不如 Hedley 的强大,但如果您已经使用 GLib,则无需添加任何内容。
回答by sharkin
Dealing with portable projects it's almost inevitable that you at some point need a section of preprocessed alternatives for a range of platforms. #ifdef this #ifdef that and so on.
在处理可移植项目时,您在某些时候需要针对一系列平台的一部分预处理替代品几乎是不可避免的。#ifdef 这个 #ifdef 那个等等。
In such a section you could very well conditionally define a way to deprecate symbols. My preference is usually to define a "warning" macro since most toolchains support custom compiler warnings. Then you can go on with a specific warning macro for deprecation etc. For the platforms supporting dedicated deprecation methods you can use that instead of warnings.
在这样的部分中,您可以很好地有条件地定义一种弃用符号的方法。我的偏好通常是定义一个“警告”宏,因为大多数工具链都支持自定义编译器警告。然后,您可以继续使用特定的警告宏以进行弃用等。对于支持专用弃用方法的平台,您可以使用它而不是警告。
回答by Contango
For Intel Compiler v19.0, use this as __INTEL_COMPILER
evaluates to 1900
:
对于英特尔编译器 v19.0,使用它作为__INTEL_COMPILER
评估1900
:
# if defined(__INTEL_COMPILER)
# define DEPRECATED [[deprecated]]
# endif
Works for the following language levels:
适用于以下语言级别:
- C++17 Support (/Qstd=c++17)
- C++14 Support (/Qstd=c++14)
- C++11 Support (/Qstd=c++11)
- C11 Support (/Qstd=c11)
- C99 Support (/Qstd=c99)
- C++17 支持 (/Qstd=c++17)
- C++14 支持 (/Qstd=c++14)
- C++11 支持 (/Qstd=c++11)
- C11 支持 (/Qstd=c11)
- C99 支持 (/Qstd=c99)
The Intel Compiler has what appears a bug in that it does not support the [[deprecated]]
attribute on certain language elements that all other compilers do. For an example, compile v6.0.0 of the (remarkly superb) {fmtlib/fmt}library on GitHub with Intel Compiler v19.0. It will break. Then see the fix in the GitHub commit.
英特尔编译器似乎存在一个错误,因为它不支持[[deprecated]]
所有其他编译器都支持的某些语言元素上的属性。例如,使用英特尔编译器 v19.0 编译 GitHub 上(非常棒的){fmtlib/fmt}库的 v6.0.0。它会破裂。然后在 GitHub commit 中查看修复。