C ++标记为已弃用

时间:2008-11-17 08:51:30

标签: c++

我在接口中有一个方法,我想用便携式C ++弃用。 当我用Google搜索时,我得到的是微软特定的解决方案; #pragma deprecated__declspec(deprecated)

二等奖解决方案是ifdef MSVC和GCC解决方案 感谢

7 个答案:

答案 0 :(得分:164)

在C ++ 14中,您可以使用[[deprecated]]属性将函数标记为已弃用(请参见第7.6.5节[dcl.attr.deprecated])。

  

attribute-token deprecated可用于标记仍然允许使用的名称和实体,但由于某种原因不鼓励。

例如,不推荐使用以下函数foo

[[deprecated]]
void foo(int);

可以提供描述不推荐使用名称或实体的原因的消息:

[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);

消息必须是字符串文字。

有关详细信息,请参阅“Marking as deprecated in C++14”

答案 1 :(得分:122)

这应该可以解决问题:

#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>因为这将被preprocesor解释为将2个参数传递给DEPRECATED宏。在这种情况下,您必须键入dede返回类型。

编辑:更简单(但可能不太广泛兼容)版本here

答案 2 :(得分:50)

以下是我2008 answer的简化版:

#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);

另见:

答案 3 :(得分:21)

在GCC中,您可以使用不推荐使用的属性声明您的函数:

void myfunc() __attribute__ ((deprecated));

当在.c文件中使用该函数时,这将触发编译时警告。

您可以在“诊断实用程序”下找到更多信息 http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html

答案 4 :(得分:4)

处理便携式项目时,您在某些时候需要为一系列平台提供一部分预处理替代方案,这几乎是不可避免的。 #ifdef这个#ifdef等等。

在这样的部分中,您可以有条件地定义一种弃用符号的方法。我的偏好通常是定义一个“警告”宏,因为大多数工具链都支持自定义编译器警告。然后,您可以继续使用特定的警告宏进行弃用等。 对于支持专用弃用方法的平台,您可以使用它而不是警告。

答案 5 :(得分:3)

以下是2018年的更完整答案。

现在,许多工具不仅可以将某些内容标记为已弃用,还可以提供消息。这允许您告诉人们什么时候被弃用,并且可能将它们指向替代品。

编译器支持仍有很多种:

  • C ++ 14支持[[deprecated]] / [[deprecated(message)]]
  • GCC 4.0+和ARM 4.1 + 支持
  • __attribute__((deprecated))
  • __attribute__((deprecated))__attribute__((deprecated(message)))支持:
    • GCC 4.5 +
    • 伪装成GCC 4.5+的几个编译器(通过设置__GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__
    • 英特尔C / C ++编译器至少返回16(您不能信任__GNUC__ / __GNUC_MINOR__,他们只是将其设置为安装的任何GCC版本)
    • ARM 5.6 +
  • 自13.10(Visual Studio 2003)
  • 以来,MSVC支持__declspec(deprecated)
  • 自14.0(Visual Studio 2005)
  • 以来,MSVC支持__declspec(deprecated(message))

您还可以基于[[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

如果你不想使用Hedley,我会把它作为练习来弄清楚如何摆脱*_VERSION_CHECK*_HAS_ATTRIBUTE宏(我写的很多Hedley所以我不会'我必须定期考虑这个问题。)

如果您使用GLib,则可以使用G_DEPRECATEDG_DEPRECATED_FOR宏。它们不像Hedley那样强大,但如果你已经使用了GLib,那就无需添加任何内容了。

答案 6 :(得分:1)

对于Intel Compiler v19.0,将其用作limits的值为__INTEL_COMPILER

1900

适用于以下语言级别:

  • C ++ 17支持(/ Qstd = c ++ 17)
  • C ++ 14支持(/ Qstd = c ++ 14)
  • C ++ 11支持(/ Qstd = c ++ 11)
  • C11支持(/ Qstd = c11)
  • C99支持(/ Qstd = c99)

Intel编译器出现了一个错误,即它不支持所有其他编译器都支持的某些语言元素上的# if defined(__INTEL_COMPILER) # define DEPRECATED [[deprecated]] # endif 属性。例如,使用Intel Compiler v19.0在GitHub上编译{fmtlib/fmt}库(非常出色)fix in the GitHub commit的v6.0.0。会破裂的。然后查看How to extract certain length of numbers from a string in python?