Рассмотрим этот код:
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
, который проверяется, имеет ли его условие побочные эффекты?