Поделиться через


__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;

Завершение блока, относящегося только к системам Майкрософт

См. также

Встроенные компоненты компилятора
Ключевые слова