Подтвердить что ты не робот

Использование assert, чтобы помочь компилятору лучше оптимизировать

Рассмотрим этот код:

void foo(int n) {
    assert(n>=0&&n<=3);

    for (int i=0; i<n; i++) {
        doSomething();
    }
}

Здесь существует утверждение: n находится между [0; 3]. Проверки, обычно используемые для проверки ошибок программиста. Но здесь он может использоваться как подсказка для компилятора, что n находится между [0; 3], поэтому он может оптимизироваться лучше. Возможно, он может развернуть цикл и использовать скачок.

Для GCC мы можем помочь компилятору вручную:

if (!(n>=0&&n<=3)) __builtin_unreachable();

Здесь GCC фактически был проинформирован о том, что n находится между [0; 3], поэтому он может генерировать лучший код.

Мой вопрос: возможно ли создать макрос new_assert (возможно, зависимый от компилятора), который может рассказать подсказки компилятору в версиях сборки? Это решение должно быть прозрачным, поэтому это может быть полная замена макроса assert. Например, в "new_assert(func());" func() не должно вызываться в сборках релизов, если оно имеет побочные эффекты.

Или, если это невозможно, может быть полезен другой полезный new_assert, если условию не разрешено иметь побочные эффекты (это вызовет ошибку времени компиляции), поэтому мы можем использовать if (!(cond)) __builtin_unreachable(); в выпусках без страх, что cond имеет побочный эффект. То есть возможно ли создать new_assert, который проверяется, имеет ли его условие побочные эффекты?

Этот вопрос является связанным с этим вопросом.

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

4b9b3361

Ответ 1

Я считаю, что если вы просто добавите неопределенное поведение в макрос new_assert(), компилятор решит, что эти предварительные условия не подлежат обсуждению. и генерировать более быстрый код.

Однако, если ваш код глючит, и утверждение не удается, все может произойти.

Ответ 2

Вы можете использовать кроссплатформенный макрос assure' from 'из GNU Gnulib.