2

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

rocambille
  • 15,398
  • 12
  • 50
  • 68
Isac Casapu
  • 1,163
  • 13
  • 21
  • Do you use any tool like CMake? – rocambille Dec 19 '16 at 14:18
  • No, just Eclipse's built-in builder – Isac Casapu Dec 19 '16 at 14:30
  • Note that I have gone over http://stackoverflow.com/questions/295120/c-mark-as-deprecated/21192071#21192071 , and I'm looking for a more infrestructure-based solution. – Isac Casapu Dec 19 '16 at 14:32
  • An infrastructure based solution would be to target a compiler that supports C++14. – eerorika Dec 19 '16 at 14:59
  • I've switched to C++ 14 mode wherever it is supported, unfortuantely one of our environment doesn't officially support C++ beyond 11 for the time being. So I'm trying to keep the codebase tidy until we can switch to C++ 14 on all platforms. – Isac Casapu Dec 19 '16 at 15:44
  • @user2079303 there are no compilers that support C++11 formally (that is none are fully compliant), only partial support. There is no stable C++14 compatible compilers. One way to make those declarations is to have some macro definition that is either empty or containing deprecated. Or macro that would wrap around the declaration.. – Swift - Friday Pie Dec 20 '16 at 06:42

2 Answers2

7

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")
Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524
rocambille
  • 15,398
  • 12
  • 50
  • 68
  • Thanks, this was instructive to read! however I don't expect to switch build systems in the near future... – Isac Casapu Dec 20 '16 at 14:23
  • @YitzikC you don't need to: just use the code I extracted for g++. If you want other compilers, use cmake with the given snippet to generate a more complete code, and use it in your project with your build system – rocambille Dec 20 '16 at 18:55
2
#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 {};
Toby Speight
  • 27,591
  • 48
  • 66
  • 103
Chnossos
  • 9,971
  • 4
  • 28
  • 40