Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++20

C++ Helps Your Compiler to Help You

0.00/5 (No votes)
22 Apr 2023CPOL2 min read 5.8K  
How compiler helps code run faster and generates warnings in single cross-compiler way
In this post, you will learn how the compiler can help our code to run faster, and how it can generate some warnings in a single cross-compiler way.

On previous articles, we saw how to create constexpr functions which can evaluate at compile time, and how to communicate with the compiler using pragma directive. In this article, we’ll see how the compiler can help our code to run faster, and how it can generate some warnings in a single cross-compilers way.

Attributes

Attributes are the unified syntax for compiler extensions, such as the GNU and IBM language extensions __attribute__((…)), Microsoft extension __declspec(), etc.

Attributes can be used almost everywhere in the code, according to the action of the attribute. Some attributes have rules which force them to be in specific places and eliminate the option to place them in other ones.

Syntax

  • [[attribute-list]] // comma separated list (Since C++11)
  • [[using attribute-namespace : attribute-list]] // all the attributes in this list belong to the same namespace. (Since C++17)

Today, there are four types of attributes:

  • [[identifier]] – A simple attribute
  • [[attribute-namespace::identifier]] – An attribute with a namespace
  • [[identifier(argument-list)]] – An attribute with arguments
  • [[attribute-namespace::identifier(argument-list)]] – An attribute with both a namespace and an argument list

Standard Attributes

[[noreturn]] (C++11) Indicates that the function does not return any value
[[deprecated]] (C++14)
[[deprecated("reason")]] (C++14)
Indicates that the use of the name or entity declared with this attribute is allowed, but discouraged for some reason.
Usually deprecated features will be removed in future releases of an API.
[[fallthrough]] (C++17) Indicates that the fall through from the previous case label is intentional and should not be diagnosed by a compiler that warns on fall-through.
[[nodiscard]] (C++17)
[[nodiscard("reason")]] (C++20)
Encourages the compiler to issue a warning if the return value is discarded.
[[maybe_unused]] (C++17) Suppresses compiler warnings on unused entities, if any
[[likely]] (C++20)
[[unlikely]] (C++20)
Indicates that the compiler should optimize for the case where a path of execution through a statement is more or less likely than any other path of execution.

cppreference – Attributes

For more standard attributes, see cppreference – attributes.

Examples

C++
[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
inline int f(); // declare f with four attributes
 
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]
int f();        // same as above, 
                // but uses a single attr specifier that contains four attributes
 
// C++17:
[[using gnu : const, always_inline, hot]] [[nodiscard]]
int f[[gnu::always_inline]](); // an attribute may appear in multiple specifiers
 
int f() { return 0; }

int main() {
    int k [[maybe_unused]];    // Without warning
    int num;
    int res = 1;
    std::cin >> num;
    switch (num) {
        case 0:
            res++;
            [[fallthrough]];

        [[likely]] case 1:     // Optimized by compiler
            res++;
            break;

        [[unlikely]] case 2:
            res--;
            break;
    }
    std::cout << res << std::endl;
    return EXIT_SUCCESS;
}

Compatibility between Compilers

To keep the compatibility between different compilers, unknown attributes will be ignored, and the compiler will warn about them. This way, when you compile the same code which uses a specific compiler attributes, using two different compilers, the code will compile in both of them, and the attribute will have the effect only on the one which supports it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)