C++17: Attributes
C++17 introduces three new code attributes:
- [[fallthrough]]
- [[maybe_unused]]
- [[nodiscard]]
The first one was discussed in detail in my C++17: Fallthrough in switch statements blog post. The others are briefly explained below.
[[maybe_unused]]
This attribute can be used to mark variables or functions that might be unused to avoid the compiler from generating a warning for such variables and functions.
For example, suppose you have code as follows:
bool DoSomething() { // ... do something ... return true; } int main() { bool result = DoSomething(); assert(result); }
When you build a release build of your code, the assert() macro becomes a no-operation. As such, in release builds, the result variable is unused, while in debug you need the result variable for the assert(). To avoid the compiler warning, use the [[maybe_unused]] attribute as follows:
int main() { [[maybe_unused]] bool result = DoSomething(); assert(result); }
This attribute can also be used on functions. Maybe you have a function that is only executed in debug. In such a case, you can mark the function with the attribute. For example:
static bool OnlyUsedInDebug() { return true; } int main() { assert(OnlyUsedInDebug()); }
When compiling with gcc, the compiler gives the following warning:
warning: ‘bool OnlyUsedInDebug()’ defined but not used [-Wunused-function]
The avoid this warning, use [[maybe_unused]]:
[[maybe_unused]] static bool OnlyUsedInDebug() { return true; }
[[nodiscard]]
This attribute can be used to make sure the caller of a function does not just discard the return value of that function. For example:
bool DoSomething() { return true; } int main() { DoSomething(); }
The user is not doing anything with the return value of the DoSomething() function, but the compiler will not give any warning about this. Now, the following code adds the [[nodiscard]] attribute:
[[nodiscard]] bool DoSomething() { return true; }
When you try to call it as in the previous main() function, the compiler will complain with something as follows:
warning C4834: discarding return value of function with ‘nodiscard’ attribute
Wassili said,
Wrote on June 21, 2018 @ 7:42 am
Thanks for an example with assertion (debug/release mode).
I have a question: Is it planned to create/standardise the api for user defined attributes?
Marc Gregoire said,
Wrote on June 21, 2018 @ 8:51 am
Wassili: I have no idea if there will be a standardized API to create user defined attributes. However, I don’t know what users would do with that. Those attributes are meant to give extra information to the compiler, so for compiler vendors it can definitely make sense to add vendor-specific attributes. A compiler vendor can introduce whatever attributes they want, but it’s recommended that they use something like [[vendorname::attribute]].