我想在便携式C ++中弃用一个接口中的方法。当我用谷歌搜索时,我得到的只是一个针对微软的解决方案。#pragma已弃用,__declspec(已弃用)。
二等奖解决方案是ifdef MSVC和GCC解决方案。
谢谢
我想在便携式C ++中弃用一个接口中的方法。当我用谷歌搜索时,我得到的只是一个针对微软的解决方案。#pragma已弃用,__declspec(已弃用)。
二等奖解决方案是ifdef MSVC和GCC解决方案。
谢谢
Answers:
在C ++ 14中,您可以使用[[deprecated]]
属性将功能标记为已弃用(请参见7.6.5 [dcl.attr.deprecated])。
该属性令牌
deprecated
可以用来标记的名称和它的使用仍然是允许的实体,但不鼓励出于某种原因。
例如,foo
不推荐使用以下功能:
[[deprecated]]
void foo(int);
可以提供一条消息,描述不赞成使用名称或实体的原因:
[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);
该消息必须是字符串文字。
有关更多详细信息,请参见“在C ++ 14中标记为已弃用”。
这应该可以解决问题:
#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);
但是,如果函数返回类型的名称中带有逗号,则会遇到问题,例如std::pair<int, int>
,这将由前处理器解释为将2个参数传递给DEPRECATED宏。在这种情况下,您将必须键入def返回类型。
编辑:简单(但可能不太广泛兼容)的版本在这里。
__declspec(deprecated)
现在相同的位置,因此可以简化宏。
这是我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);
也可以看看:
[[deprecate]]
弃用宏?:-)
DEPRECATED void foo(...);
而是用它代替DEPRECATED(void foo(...));
在GCC中,您可以使用已弃用的属性声明函数,如下所示:
void myfunc() __attribute__ ((deprecated));
在.c文件中使用该函数时,将触发编译时警告。
您可以在http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html的 “诊断实用程序”下找到更多信息。
这是2018年的更完整答案。
如今,许多工具不仅使您可以将某项标记为已弃用,还可以提供消息。这使您可以告诉人们何时不推荐使用某些产品,甚至可以将其指向替代产品。
编译器支持仍然有很多种类:
[[deprecated]]
/[[deprecated(message)]]
。__attribute__((deprecated))
由GCC 4.0+和ARM 4.1+支持__attribute__((deprecated))
和 __attribute__((deprecated(message)))
支持:
__GNUC__
/ __GNUC_MINOR__
/__GNUC_PATCHLEVEL__
)__GNUC__
/__GNUC_MINOR__
,他们只是将其设置为已安装的GCC的任何版本)__declspec(deprecated)
从13.10开始(Visual Studio 2003)__declspec(deprecated(message))
从14.0开始支持MSVC (Visual Studio 2005)您还可以[[gnu::deprecated]]
在C ++ 11的最新版本的clang中使用,具体取决于__has_cpp_attribute(gnu::deprecated)
。
我在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
我将其保留为练习,以弄清楚如何摆脱*_VERSION_CHECK
和*_HAS_ATTRIBUTE
如果您不想使用Hedley的话宏(我写Hedley的主要目的是因为我不必定期考虑这一点)。
如果使用GLib,则可以使用G_DEPRECATED
和G_DEPRECATED_FOR
宏。它们不像Hedley的那样健壮,但是如果您已经使用GLib,则无需添加任何内容。
对于Intel Compiler v19.0,将其用作__INTEL_COMPILER
评估1900
:
# if defined(__INTEL_COMPILER)
# define DEPRECATED [[deprecated]]
# endif
适用于以下语言级别:
英特尔编译器存在一个似乎有错误的地方,即它不支持[[deprecated]]
所有其他编译器都支持的某些语言元素的属性。例如,使用Intel Compiler v19.0编译GitHub上{fmtlib / fmt}库(非常出色)的v6.0.0。会破裂的。然后在GitHub commit中查看修复。