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
https://godbolt.org/z/8arY74Gsd