C++标记为已弃用

Die*_*rik 140 c++

我在接口中有一个方法,我想用便携式C++弃用.当我用Google搜索时,我得到的只是Microsoft特定的解决方案; #pragma deprecated__declspec(不建议使用).

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

Jos*_*eld 175

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

属性令牌 deprecated可以用来标记的名称和它的使用仍然是允许的实体,但不鼓励出于某种原因.

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

[[deprecated]]
void foo(int);
Run Code Online (Sandbox Code Playgroud)

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

[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);
Run Code Online (Sandbox Code Playgroud)

消息必须是字符串文字.

有关更多详细信息,请参阅"在C++ 14中标记为已弃用".

  • @Zammbi您应该能够,因为宏在编译之前由预处理器处理。[[deprecated]]应该出现在宏的评估位置(并让编译器输出相关的警告)。 (2认同)
  • 那么 C++11 怎么样? (2认同)

Mic*_*ngs 125

这应该做的伎俩:

#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);
Run Code Online (Sandbox Code Playgroud)

但是,如果函数返回类型的名称中包含逗号,则会遇到问题,例如std::pair<int, int>,这将由preprocesor解释为将2个参数传递给DEPRECATED宏.在这种情况下,您必须键入dede返回类型.

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

  • 而不是#error,最好是#define DEPRECATED(func)func (5认同)
  • gcc的属性语法允许属性现在与`__declspec(不建议使用)`在同一个位置,因此可以简化宏. (3认同)
  • 是的,我会选择“#warning You need to Implement DEPRECATED for this compiler”,或者类似的内容。如果这是不可能的,那么搬运工可以#define DEPRECATED(FUNC) FUNC,并且无需它即可生活。 (2认同)
  • 不幸的是,没有标准的方法在C++中输出编译警告:P #pragma消息必须要做. (2认同)

Mic*_*ngs 53

这是我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);
Run Code Online (Sandbox Code Playgroud)

也可以看看:

  • 你如何`[[弃用]]`你不推荐使用的宏?:-) (15认同)
  • 您应该编辑2008年答案而不是发布新答案. (12认同)
  • 你不必将它包装在函数周围,所以它是`DEPRECATED void foo(...);`而不是`DEPRECATED(void foo(...));` (4认同)
  • 我看不出这两个答案之间有任何显着差异.你为什么第二次发布它? (3认同)
  • 这可能不像我的其他答案那样广泛兼容,因此我单独添加了这个. (3认同)
  • 如果您想更加完善,也可以添加消息,例如`DEPRECATED(“ Use bar相反”)void foo(...);` (2认同)
  • @graham.reeds,没有办法在宏上使用 C++ 属性,但如果您只想在调用宏时发出警告,那么在 GCC 4.8+ 以及其他一些编译器中,您可以执行以下操作: #define DEPRECATED _Pragma("GCC 警告 \"DEPRECATED 已弃用\"")`。MSVC 还有一个编译指示:`#define DEPRECATED __pragma(message("DEPRECATED is deprecated"))`。如果您接受信息性消息而不是警告,您可以从其他一些编译器获得支持......看看 [`HEDLEY_WARNING`](https://github.com/nemequ/hedley/blob/936b674230258626cac025b37d7af8eefc66b8df/hedley.h #L1776) (2认同)

Ter*_*kal 21

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

void myfunc() __attribute__ ((deprecated));
Run Code Online (Sandbox Code Playgroud)

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

您可以在http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html上的 "Diagnostic pragmas"下找到更多信息.


nem*_*equ 6

这是2018年的更完整答案。

如今,许多工具不仅使您可以将某项标记为已弃用,还可以提供消息。这使您可以告诉人们何时不推荐使用某些产品,甚至可以将其指向替代产品。

编译器支持仍然有很多种类:

  • 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开始支持MSVC (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
Run Code Online (Sandbox Code Playgroud)

我将把它作为练习,以弄清楚如果您不想使用Hedley的话,该如何摆脱*_VERSION_CHECKand *_HAS_ATTRIBUTE宏(我写Hedley的主要目的是因为我不必定期考虑这一点)。

如果使用GLib,则可以使用G_DEPRECATEDG_DEPRECATED_FOR宏。它们的功能不如Hedley的功能强大,但是如果您已经使用GLib,则无需添加任何内容。