Как использовать вероятный / маловероятный атрибут C++20 в операторе if-else

Этот вопрос о C++20 [[likely]]/[[unlikely]] особенность, а не определяемые компилятором макросы.

В этих документах ( cppreference) приведен только пример их применения к оператору switch-case. Этот пример случая переключения прекрасно компилируется с моим компилятором (g++-7.2), поэтому я предполагаю, что компилятор реализовал эту функцию, хотя она еще официально не представлена ​​в текущих стандартах C++.

Но когда я использую их так: if (condition) [[likely]] { ... } else { ... }Я получил предупреждение:

msgstr "предупреждение: атрибуты в начале оператора игнорируются [-Wattributes]".

Так как же мне использовать эти атрибуты в операторе if-else?

2 ответа

Решение

Основываясь на примере из отчета Jacksonville'18 ISO C++, синтаксис правильный, но кажется, что он еще не реализован:

if (a>b) [[likely]] {

10.6.6 Атрибуты правдоподобия [dcl.attr.likelihood] draft

На сегодняшний день cppreference утверждает, что, например,likely (курсив мой):

Применяется к оператору, чтобы позволить компилятору оптимизировать для случая, когда пути выполнения, включающие этот оператор, более вероятны, чем любой альтернативный путь выполнения, который не включает такой оператор.

Это говорит о том, что место для размещения атрибута находится в наиболее вероятном утверждении, то есть:

if (condition) { [[likely]] ... } else { ... }

Этот синтаксис принят, например, Visual Studio 2019 16.7.0 при компиляции с /std:c++latest.

Так как же мне использовать эти атрибуты в операторе if-else?

Точно так же, как вы делаете, ваш синтаксис правильный в соответствии с примером, приведенным в проекте стандарта (упрощенно, чтобы показывать только соответствующие биты):

int f(int n) {
    if (n > 5) [[unlikely]] {
        g(0);
        return n * 2 + 1;
    }

    return 3;
}

Но вы должны понимать, что эта функция является относительно новой, поэтому в реализациях могут быть только заполнители, позволяющие вам устанавливать атрибуты. Это видно из вашего предупреждающего сообщения.


Вы также должны понимать, что, если определенные формулировки между последним проектом и конечным продуктом не изменятся, даже совместимые реализации могут игнорировать эти атрибуты. Это очень много предложений для компилятора, как inline в C. Из этого последнего проекта n4762 (во время этого ответа и с моим акцентом):

Примечание. Использование вероятного атрибута предназначено для того, чтобы позволить реализациям оптимизировать ситуацию, когда пути выполнения, включая его, произвольно более вероятны, чем любой альтернативный путь выполнения, который не включает такой атрибут в операторе или метке.

Обратите внимание на слово "разрешить", а не "принудительно", "требовать" или "мандат".

Другие вопросы по тегам