Skip to content

Instantly share code, notes, and snippets.

@MisterDA
Last active December 11, 2024 10:09
Show Gist options
  • Save MisterDA/edbdc396485f1cda9346235dd37f0ae8 to your computer and use it in GitHub Desktop.
Save MisterDA/edbdc396485f1cda9346235dd37f0ae8 to your computer and use it in GitHub Desktop.
Portable deprecation notice for C compilers
#ifndef __has_attribute
#define __has_attribute(x) 0
#endif
#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L || \
defined(__cplusplus) && __cplusplus >= 201402L
#define CAMLdeprecated(name, replacement) \
[[deprecated("use '" #replacement "' instead")]]
#elif __has_attribute(deprecated) || defined(__GNUC__)
#define CAMLdeprecated(name, replacement) \
__attribute__((deprecated("use '" #replacement "' instead")))
#elif defined(_MSC_VER)
#define CAMLdeprecated(name, replacement) \
__declspec(deprecated("is deprecated, use " #replacement " instead"))
#else
#define CAMLdeprecated(name, replacement)
#endif
#define CAMLstringify(x) #x
#if defined(__llvm__)
#define CAMLdeprecated_macro(name, replacement) \
_Pragma(CAMLstringify(GCC warning "'" #name "' is deprecated: " \
"use '" #replacement "' instead"))
#elif defined(__GNUC__)
#define CAMLmakewarning(x) CAMLstringify(GCC warning x)
#define CAMLdeprecated_macro(name, replacement) \
_Pragma(CAMLmakewarning(CAMLstringify(name is deprecated: \
use replacement instead)))
#elif defined(_MSC_VER)
#define CAMLdefer(M,...) M(__VA_ARGS__)
#define CAMLmakewarning(x) _Pragma(CAMLstringify(message(x)))
#define CAMLdeprecated_macro(name, replacement) \
CAMLmakewarning(__FILE__ "(" CAMLdefer(CAMLstringify,__LINE__) "): '" \
#name "': is deprecated, use " #replacement " instead")
#else
#define CAMLdeprecated_macro(name, replacement)
#endif
#define CAMLdeprecated_typedef(name, type) \
CAMLdeprecated_macro(CAMLdeprecated_typedef, CAMLdeprecated) \
CAMLdeprecated(name, unknown) \
typedef type name
typedef void * T;
struct CAMLdeprecated(S1, S2) S1 { int s; };
CAMLdeprecated(PT1, PT2) typedef T* PT1;
CAMLdeprecated_typedef(PT3, T*);
CAMLdeprecated(x1, x2) int x1 = 0;
union U { CAMLdeprecated(n1, n2) int n1; };
CAMLdeprecated(f1, f2) void f1(void) {};
enum CAMLdeprecated(E1, E2) E1 { E };
#if !defined(_MSC_VER)
enum { A1 CAMLdeprecated(A1, A2), B1 CAMLdeprecated(B1, B2) = 42 };
#endif
void h(void) {};
#define g \
CAMLdeprecated_macro(g, h) \
h
int main(void) {
struct S1 s;
PT1 p;
PT3 q;
x1 = 42;
union U u = { .n1 = 36 };
f1();
enum E1 e;
#if !defined(_MSC_VER)
int a = A1;
int b = B1;
#endif
g();
}
/*
- https://en.cppreference.com/w/c/language/attributes/deprecated
- https://learn.microsoft.com/en-us/cpp/preprocessor/deprecated-c-cpp?view=msvc-170
- https://learn.microsoft.com/en-us/cpp/cpp/deprecated-cpp?view=msvc-170
- https://gcc.gnu.org/onlinedocs/cpp/Pragmas.html
- https://gcc.gnu.org/onlinedocs/gcc-14.2.0/gcc/Common-Type-Attributes.html#index-deprecated-type-attribute
- https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment