Isac Casapu
Isac Casapu

Reputation: 1301

A portable way to mark a C++ declaration as deprecated that would be accepted by C++ 11

C++ 14 finally added the [[deprecated]] attribute. I'd like to use it in header files which also need to be consumed in C++ 11 mode without choking.

I don't mind if the deprecation is ignored in C++ 11 mode.

I haven't been able to find a Boost macro that wraps this language feature portably, so I've added before each declaration that I want to deprecate the following code:

#if __cplusplus >= 201402L
[[deprecated]]
#endif

Any suggestions for making this cleaner using Boost or another common library?

Note: I'm targetting primarily G++ 4.8 and 5.x

Upvotes: 2

Views: 1168

Answers (2)

Chnossos
Chnossos

Reputation: 10486

#if __cplusplus >= 201402L
# define DEPRECATED          [[deprecated]]
# define DEPRECATED_MSG(msg) [[deprecated(msg)]]
#else
# define DEPRECATED
# define DEPRECATED_MSG(msg)
#endif

Usage:

class DEPRECATED_MSG("Use class Y instead") X {};

Upvotes: 2

rocambille
rocambille

Reputation: 15996

Would you have used CMake, you could have handled [[deprecated]] attribute using preprocessor directives generated with the CMake module WriteCompilerDetectionHeader:

include(WriteCompilerDetectionHeader)

write_compiler_detection_header(
    FILE foo_compiler_detection.h
    PREFIX foo
    COMPILERS GNU
    FEATURES cxx_attribute_deprecated
)

I tried it, and extracted the code tied to your primary target g++ from the generated file:

# define foo_COMPILER_IS_GNU 0

#if defined(__GNUC__)
# undef foo_COMPILER_IS_GNU
# define foo_COMPILER_IS_GNU 1
#endif

#  if foo_COMPILER_IS_GNU
#    if (__GNUC__ * 100 + __GNUC_MINOR__) >= 409 && __cplusplus > 201103L
#      define foo_COMPILER_CXX_ATTRIBUTE_DEPRECATED 1
#    else
#      define foo_COMPILER_CXX_ATTRIBUTE_DEPRECATED 0
#    endif
#  endif

#  ifndef foo_DEPRECATED
#    if foo_COMPILER_CXX_ATTRIBUTE_DEPRECATED
#      define foo_DEPRECATED [[deprecated]]
#      define foo_DEPRECATED_MSG(MSG) [[deprecated(MSG)]]
#    elif foo_COMPILER_IS_GNU
#      define foo_DEPRECATED __attribute__((__deprecated__))
#      define foo_DEPRECATED_MSG(MSG) __attribute__((__deprecated__(MSG)))
#    else
#      define foo_DEPRECATED
#      define foo_DEPRECATED_MSG(MSG)
#    endif
#  endif

I guess that's the most complete code you could produce for g++. If you need to support other compilers, add them to the COMPILERS line in the CMake code above, and rerun CMake to update the generated file.


Once included, this code will allow you to replace your original:

#if __cplusplus >= 201402L
[[deprecated]]
#endif

With:

foo_DEPRECATED

Or, using the version with a message:

foo_DEPRECATED_MSG("this feature is deprecated, use the new one instead")

Upvotes: 7

Related Questions