The problem I am facing when using the below macro
// Assume that __GNUC__ or __clang__ is defined.
#if defined(__has_c_attribute)
#if __has_c_attribute(deprecated)
#define ATTRIBUTE_DEPRECATED(...) [[deprecated(__VA_ARGS__)]]
#endif /* deprecated */
#else
#define ATTRIBUTE_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__)))
#endif /* __has_c_attribute */
is that __attribute__((deprecated()))
and __attribute__((deprecated))
are equivalent, but [[deprecated()]]
and [[deprecated]]
are not.
The #else
block works correctly when called with either of these:
ATTRIB_DEPRECATED()
ATTRIB_DEPRECATED("privat")
because GNU C allows the parameter-list of the attribute to be empty.
But when compiling with std=c2x
, the #if
block does not, and fails with:
deprecated.c:12:14: error: parentheses must be omitted if attribute argument list is empty
Is there a way I can get the same code to work with C23 as well?
It'd also be nicer if I could write:
ATTRIB_DEPRECATED
instead of:
ATTRIB_DEPRECATED()
if no argument was to be provided.
For a MRE:
// Assume that __GNUC__ or __clang__ is defined.
#if defined(__has_c_attribute)
#if __has_c_attribute(deprecated)
#define ATTRIBUTE_DEPRECATED(...) [[deprecated(__VA_ARGS__)]]
#endif
#else
#define ATTRIBUTE_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__)))
#endif /* __has_c_attribute */
ATTRIBUTE_DEPRECATED() int min(int a, int b)
{
return a < b ? a : b;
}
int main() {
return min(10, 20);
}
The above code would only compile f __has_c_attribute
was not defined.
I believe you have to have two separate macros for that
#if defined(__has_c_attribute)
#if __has_c_attribute(deprecated)
#define ATTRIBUTE_DEPRECATED [[deprecated]]
#define ATTRIBUTE_DEPRECATEDR(...) [[deprecated(#__VA_ARGS__)]]
#endif
#else
#define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#define ATTRIBUTE_DEPRECATEDR(...) __attribute__((deprecated))
#endif /* __has_c_attribute */
ATTRIBUTE_DEPRECATEDR(this is test) int min(int a, int b)
{
return a < b ? a : b;
}
ATTRIBUTE_DEPRECATED int max(int a, int b)
{
return a > b ? a : b;
}
int main() {
return min(max(10,20), max(10, 20));
}