Outils pour utilisateurs

Outils du site


lang:cpp:condition

Ceci est une ancienne révision du document !


Table des matières

if

Condition classique

if ()
{
  plusieurs instructions;
}
else if ()
  une instruction;
else
  une instruction;

Attention aux else s'il y a des if imbriqués :

if ()
  if ()
    une instruction;
else // Ici, l'indentation est mauvaise car le else correspond au second if.
  une instruction;

fold

Avec les templates variadiques :

template <class T, class... Ts>
constexpr bool isin(T&& val, Ts&&... arg)
{
  // Toutes les parenthèses sont nécessaires.
  return ((arg == val) || ...);
}
 
int main()
{
  if constexpr(isin(1, 0, 2, 3, 4, 5))
    return 0;
  else
    return 1;
}

C++ et les Fold Expressions Archive du 2016/11/27 le 05/01/2020

switch

Cas courant

Les switch/case agissent comment des goto. Il faut donc mettre un break pour éviter de passer à l'instruction suivante.

int i = 0;
switch (i)
{
  case 0:
    i = 2;
    // break;
    // Sans break, l'instruction i = 3 sera executée.
  case 1:
    i = 3;
  case 2:
  default:
}

Sur un string

switch ne fonctionne sur que les nombres. Pour utiliser un string, il faut passer par une fonction de hash (ici, djb2).

constexpr unsigned long djb2(char const *str)
{
    unsigned long hash = 5381;
    int c = 0;
 
    while ((c = *str++))
        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
 
    return hash;
}
 
int main()
{
  std::string texte = "texte";
  switch (djb2(texte.c_str()))
  {
    case djb2("texte"):
      texte = "OK";
      break;
  }
}

<note important>Toute création d'un hash présente un risque de collision.</note>

constexprhash github Archive du 24/08/2016 le 05/01/2020

[[unlikely]] et [[likely]]

Il est possible d'indiquer au compilateur si une condition est généralement vraie ou fausse. Cela fonctionne sur if et case.

int i = 1;
if (i == 1) [[likely]]
  ...
int f(int i)
{
  switch(i)
  {
    case 1: return 1;
    [[likely]]
    case 2: return 2;
    [[unlikely]]
    default: return 3;
  }
  return 2;
}

Code généré sans les attributs [[likely]] et [[unlikely]].

gcc est utilisé et les options d'optimisation doivent être activées au minimum niveau 1.

f(int):
  mov     eax, edi
  cmp     edi, 1
  je      .L2
  cmp     edi, 2
  mov     edx, 3
  cmovne  eax, edx
.L2:
  ret

Code généré avec les attributs [[likely]] et [[unlikely]].

f(int):
  mov     eax, edi
  cmp     edi, 1
  je      .L2
  cmp     edi, 2
  jne     .L8
.L2:
  ret
.L8:
  mov     eax, 3
  ret
lang/cpp/condition.1580791209.txt.gz · Dernière modification : 2020/02/04 05:40 de root