In C++14, you can mark a function as deprecated using the [[deprecated]]
attribute (see section 7.6.5 [dcl.attr.deprecated]).
The attribute-token
deprecated
can be used to mark names and entities whose use is still allowed, but is discouraged for some reason.
For example, the following function foo
is deprecated:
[[deprecated]]
void foo(int);
It is possible to provide a message that describes why the name or entity was deprecated:
[[deprecated("Replaced by bar, which has an improved interface")]]
void foo(int);
The message must be a string literal.
For further details, see “Marking as deprecated in C++14”.
This should do the trick:
#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);
However, you will encounter problems if a function return type has a commas in its name e.g. std::pair<int, int>
as this will be interpreted by the preprocesor as passing 2 arguments to the DEPRECATED macro. In that case you would have to typedef the return type.
Edit: simpler (but possibly less widely compatible) version here.
Here's a simplified version of my 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);
See also:
__declspec(deprecated)
__attribute__((deprecated))
__attribute__((deprecated))
In GCC you can declare your function with the attribute deprecated like this:
void myfunc() __attribute__ ((deprecated));
This will trigger a compile-time warning when that function is used in a .c file.
You can find more info under "Diagnostic pragmas" at http://gcc.gnu.org/onlinedocs/gcc/Pragmas.html
Here is a more complete answer for 2018.
These days, a lot of tools allow you to not just mark something as deprecated, but also provide a message. This allows you to tell people when something was deprecated, and maybe point them toward a replacement.
There is still a lot of variety in compiler support:
[[deprecated]]
/[[deprecated(message)]]
.__attribute__((deprecated))
is supported by GCC 4.0+ and ARM 4.1+__attribute__((deprecated))
and __attribute__((deprecated(message)))
is supported for:
__GNUC__
/__GNUC_MINOR__
/__GNUC_PATCHLEVEL__
)__GNUC__
/__GNUC_MINOR__
, they just set it to whatever version of GCC is installed)__declspec(deprecated)
since 13.10 (Visual Studio 2003)__declspec(deprecated(message))
since 14.0 (Visual Studio 2005)You can also use [[gnu::deprecated]]
in recent versions of clang in C++11, based on __has_cpp_attribute(gnu::deprecated)
.
I have some macros in Hedley to handle all of this automatically which I keep up to date, but the current version (v2) looks like this:
#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
I'll leave it as an exercise to figure out how to get rid of the *_VERSION_CHECK
and *_HAS_ATTRIBUTE
macros if you don't want to use Hedley (I wrote Hedley largely so I wouldn't have to think about that on a regular basis).
If you use GLib, you can use the G_DEPRECATED
and G_DEPRECATED_FOR
macros. They're not as robust as the ones from Hedley, but if you already use GLib there is nothing to add.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With