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.


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();

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();

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()

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; }


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()

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


2 Comments so far »

  1. 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?

  2. 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]].

Comment RSS · TrackBack URI

Leave a Comment

Name: (Required)

E-mail: (Required)