__assume
Блок, относящийся только к системам Майкрософт
Передает подсказку оптимизатору.
Синтаксис
__assume(
expression
)
Параметры
expression
Для доступного кода любое выражение, которое предполагается оценить true
. Используется 0
для указания недоступного кода оптимизатору.
Замечания
Оптимизатор предполагает, что условие, представленное expression
true
в точке отображения ключевого слова, остается верным, пока не expression
будет изменено (например, путем назначения переменной). Выборочное использование подсказок, передаваемых оптимизатору __assume
, может улучшить оптимизацию.
__assume
Если инструкция написана как противоречие (выражение, которое всегда оцениваетсяfalse
), оно всегда рассматривается как __assume(0)
. Если код не работает должным образом, убедитесь, что expression
определенный код является допустимым и true
как описано ранее. Инструкция __assume(0)
является особым случаем. Используется __assume(0)
для указания пути кода, который не может быть достигнут.
Предупреждение
Программа не должна содержать недействительный оператор __assume
в достижимом пути. Если компилятор может достигнут недопустимого оператора __assume
, программа может повести себя непредсказуемо и иметь потенциально опасное поведение.
Для совместимости с предыдущими версиями является синонимом__assume
, _assume
если не указан параметр /Za
компилятора (отключить расширения языка).
__assume
не является подлинной внутренней. Его не нужно объявлять как функцию, и ее нельзя использовать в директиве #pragma intrinsic
. Несмотря на то, что код не создается, изменяется код, созданный с помощью оптимизатора.
Используйте __assume
только в ASSERT
том случае, если утверждение не восстанавливается. Не используйте __assume
в утверждении, для которого возникла последующая ошибка код восстановления, так как компилятор может оптимизировать код обработки ошибок.
Требования
Intrinsic | Архитектура |
---|---|
__assume |
x86, ARM, x64, ARM64, ARM64EC |
Пример
В следующем примере показано, как указать __assume(0)
, что default
не удается достичь случая инструкции switch
. Это наиболее типичное использование __assume(0)
. Здесь программист знает, что единственными возможными входными данными p
будут 1 или 2. Если другое значение передается в p
, программа становится недействительной, что приводит к ее непредсказуемому поведению.
// compiler_intrinsics__assume.cpp
void func1(int /*ignored*/)
{
}
int main(int p)
{
switch(p)
{
case 1:
func1(1);
break;
case 2:
func1(-1);
break;
default:
__assume(0);
// This tells the optimizer that the default
// cannot be reached. As so, it does not have to generate
// the extra code to check that 'p' has a value
// not represented by a case arm. This makes the switch
// run faster.
}
}
В результате инструкции __assume(0)
компилятор не создает код для проверки p
наличия значения, которое не представлено в инструкции case.
Если вы не уверены, что выражение всегда будет находиться true
во время выполнения, можно использовать assert
функцию для защиты кода. Это определение макроса упаковывает инструкцию __assume
с проверкой:
#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))
Для работы __assume(0)
оптимизации регистра default
оператор должен быть первым оператором в тексте default
дела. К сожалению, assert
в ASSUME
макросе компилятор не будет выполнять эту оптимизацию. В качестве альтернативы можно использовать отдельный макрос, как показано здесь:
#ifdef DEBUG
// This code is supposed to be unreachable, so assert
# define NODEFAULT assert(0)
#else
# define NODEFAULT __assume(0)
#endif
// . . .
default:
NODEFAULT;
Завершение блока, относящегося только к системам Майкрософт