Udostępnij za pośrednictwem


__assume

Specyficzne dla firmy Microsoft

Przekazuje wskazówkę optymalizatorowi.

Składnia

__assume(
   expression
)

Parametry

expression
W przypadku kodu osiągalnego każde wyrażenie, które przyjmuje się do wartości .true Użyj 0 polecenia , aby wskazać niemożliwy do osiągnięcia kod optymalizatora.

Uwagi

Optymalizator zakłada, że warunek reprezentowany przez expression element znajduje się w punkcie, w którym słowo kluczowe pojawia true się i pozostaje prawdziwe do momentu expression modyfikacji (na przykład przez przypisanie do zmiennej). Selektywne użycie wskazówek przekazywanych do optymalizatora przez __assume może poprawić optymalizację.

__assume Jeśli instrukcja jest zapisywana jako sprzeczność (wyrażenie, które zawsze daje wartość false), zawsze jest traktowane jako __assume(0). Jeśli kod nie działa zgodnie z oczekiwaniami, upewnij się, że expression zdefiniowany kod jest prawidłowy i true, zgodnie z wcześniejszym opisem. Instrukcja __assume(0) jest szczególnym przypadkiem. Użyj polecenia __assume(0) , aby wskazać ścieżkę kodu, która nie może zostać osiągnięta.

Ostrzeżenie

Program nie może zawierać nieprawidłowej __assume instrukcji na dostępnej ścieżce. Jeśli kompilator może osiągnąć nieprawidłową __assume instrukcję, program może spowodować nieprzewidywalne i potencjalnie niebezpieczne zachowanie.

Aby uzyskać zgodność z poprzednimi wersjami, jest synonimem, _assume __assume chyba że określono opcję /Za kompilatora (Wyłącz rozszerzenia języka).

__assume nie jest prawdziwym wewnętrznym. Nie musi być zadeklarowana jako funkcja i nie może być używana w #pragma intrinsic dyrektywie. Mimo że żaden kod nie jest generowany, wpływ na kod wygenerowany przez optymalizator ma wpływ.

Używaj __assume tylko wtedy ASSERT , gdy asercji nie można odzyskać. Nie używaj __assume asercji, dla której masz kolejny kod odzyskiwania błędów, ponieważ kompilator może zoptymalizować kod obsługi błędów.

Wymagania

Nieodłączny Architektura
__assume x86, ARM, x64, ARM64, ARM64EC

Przykład

W poniższym przykładzie pokazano, jak użyć __assume(0) polecenia , aby wskazać, że default nie można osiągnąć wielkości liter instrukcji switch . Jest to najbardziej typowe użycie metody __assume(0). W tym miejscu programista wie, że jedynymi możliwymi danymi wejściowymi p będzie 1 lub 2. Jeśli dla programu zostanie przekazana pinna wartość, program stanie się nieprawidłowy i powoduje nieprzewidywalne zachowanie.

// 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.
   }
}

W wyniku instrukcji __assume(0) kompilator nie generuje kodu w celu przetestowania, czy p ma wartość, która nie jest reprezentowana w instrukcji case.

Jeśli nie masz pewności, że wyrażenie będzie zawsze true w czasie wykonywania, możesz użyć assert funkcji w celu ochrony kodu. Ta definicja makra opakowuje instrukcję __assume za pomocą sprawdzania:

#define ASSUME(e) (((e) || (assert(e), (e))), __assume(e))

default Aby optymalizacja przypadku działała, __assume(0) instrukcja musi być pierwszą instrukcją w treści default sprawy. Niestety element assert w makrze ASSUME uniemożliwia kompilatorowi wykonanie tej optymalizacji. Alternatywnie możesz użyć oddzielnego makra, jak pokazano poniżej:

#ifdef DEBUG
// This code is supposed to be unreachable, so assert
# define NODEFAULT   assert(0)
#else
# define NODEFAULT   __assume(0)
#endif
// . . .
   default:
      NODEFAULT;

END Microsoft Specific

Zobacz też

Funkcje wewnętrzne kompilatora
Słowa kluczowe