Arene Base
Fundamental Utilities For Safety Critical C++
Loading...
Searching...
No Matches
Facilities For Specifying C++ Attributes

C++11 added the Attribute Specifier Sequence, a syntax for specifying uniformly named "attributes" with implementation defined behavior attached to types, objects code, etc.

However, not every platform and compiler supports every attribute. In addition, different customer's coding standards have different requirements with respect to behavior in the presence of an unsupported attribute. Some allow unknown attributes to be ignored, while others turn this into a compiler error.

To allow code to be written that leverages common attributes needed for accurate static analysis ([[noreturn]], [[maybe_unused]], etc), while avoiding unsupported attributes remaining in compiled code, arene-base provides helper facilities for working with attributes in the following header:

There are facilities for testing if attributes are supported by a platform, as well as pre-built macros for injecting an attribute only if the platform/compiler supports it for commonly used attributes.

ARENE_HAS_STD_ATTRIBUTE: Testing For Attribute Existence

The ARENE_HAS_STD_ATTRIBUTE(...) macro is a wrapper around the compiler intrinsics __has_cpp_attribute or __has_c_attribute. It is used to test for the existence of a given attribute with the current compiler, and is the basis from which all the "stock" attribute wrappers are constructed. For example, the wrapper for the [[maybe_unused]] attribute looks like this:

#if ARENE_HAS_STD_ATTRIBUTE(gnu::unused)
#define ARENE_MAYBE_UNUSED [[gnu::unused]]
#elif ARENE_HAS_STD_ATTRIBUTE(maybe_unused) >= 201603L
#define ARENE_MAYBE_UNUSED [[maybe_unused]]
#else
#define ARENE_MAYBE_UNUSED
#endif

This construction tests first if the compiler supports gnu::unused, the GCC-specific implementation of [[maybe_unused]] before [[maybe_unused]] was standardized. If it is defined, this is used. Otherwise, it tests if the standard maybe_unused attribute is defined, and if it is, uses it. Finally, if neither are supported, the macro turns into a no-op.

Supported Attributes

The attributes which have stock wrapper macros are enumerated in the following table, with links to their stdlib documentation for meaning:

Macro Attribute
ARENE_NODISCARD [[nodiscard]]
ARENE_NODISCARD_WITH(...) [[nodiscard(..)]], provides a message for justification.
ARENE_MAYBE_UNUSED [[maybe_unused]]
ARENE_NORETURN [[noreturn]]
ARENE_DEPRECATED [[deprecated]]
ARENE_DEPRECATED_WITH(...) [[deprecated(...)]], provides a message for justification
ARENE_MAY_ALIAS __may_alias__

And example usages:

ARENE_NODISCARD bool do_foo(Args args...);
ARENE_NORETURN void always_throws(Args args...);
ARENE_DEPRECATED_WITH("Prefer new_api(Args args...)") old_api(Args args...);
#define ARENE_DEPRECATED_WITH(...)
An alias for the [[deprecated(...)]] attribute, or a no-op if the attribute is not supported.
Definition deprecated.hpp:33
#define ARENE_NODISCARD
An alias for [[nodiscard]] , or a no-op if the attribute is not supported.
Definition nodiscard.hpp:25
#define ARENE_NORETURN
An alias for [[noreturn]] , or a no-op if the attribute is not supported.
Definition noreturn.hpp:23