Outils pour utilisateurs

Outils du site


lang:cpp:condition

Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentesRévision précédente
Prochaine révision
Révision précédente
lang:cpp:condition [2020/02/17 06:31] – Séparation du C / C++ rootlang:cpp:condition [2020/06/16 15:15] (Version actuelle) – Fix typo root
Ligne 1: Ligne 1:
 ====if==== ====if====
-===fold (opérateur ...)===+ 
 +Les ''if'' peuvent s'optimiser avec les attributs [[lang:cpp:attribut#unlikely_et_likely|unlikely et likely]]. 
 + 
 +===Conditions multiples sur une même valeur : fold (opérateur ...)===
 Avec les templates variadiques : Avec les templates variadiques :
  
Ligne 21: Ligne 24:
 [[https://h-deb.clg.qc.ca/Sujets/Divers--cplusplus/Fold-expressions.html|C++ et les Fold Expressions]] {{ :lang:cpp:condition:c_et_les_fold_expressions_2020-01-05_18_59_43_.html |Archive du 2016/11/27 le 05/01/2020}} [[https://h-deb.clg.qc.ca/Sujets/Divers--cplusplus/Fold-expressions.html|C++ et les Fold Expressions]] {{ :lang:cpp:condition:c_et_les_fold_expressions_2020-01-05_18_59_43_.html |Archive du 2016/11/27 le 05/01/2020}}
  
-====[[unlikely]] et [[likely]]==== +====switch/case====
-Il est possible d'indiquer au compilateur si une condition est généralement vraie ou fausse. Cela fonctionne sur ''if'' et ''case''.+
  
-<code cpp> +Les ''switch''/''case'' peuvent s'optimiser avec les attributs [[lang:cpp:attribut#unlikely_et_likely|unlikely et likely]]
-int i = 1; + 
-if (i == 1) [[likely]] +===Déclaration d'une variable dans un switch=== 
-  ... +Une variable définie dans un ''case'' est accessible pour tous les ''case'' le suivantOn ne peut donc définir dans un ''case'' que des variables ayant un constructeur ''default''
-</code>+ 
 +Il est donc conseillé de mettre des ''{}'' entre chaque ''case''.
  
 <code cpp> <code cpp>
-int f(int i)+class A
 { {
-  switch(i)+    public: 
 +    A() = default; 
 +}; 
 + 
 +class B 
 +
 +    public: 
 +    B(){} 
 +}; 
 + 
 +int main() 
 +
 +  int i = 0; 
 +  switch (i) 
 +  { 
 +  case 0: 
 +    // Valide car la classe A a un constructeur default. 
 +    A a; 
 +    // Non car si i vaut 1, le constructeur b ne sera pas appelé. 
 +    // error: cannot jump from switch statement to this case label 
 +    // B b1; 
 +    break; 
 +  case 1:
   {   {
-    case 1: return 1+    // Valide car b2 ne sera pas accessible en dehors de case 1
-    [[likely]] +    B b2
-    case 2: return 2; +    break; 
-    [[unlikely]] +  } 
-    default: return 3;+  case 2: 
 +  default: 
 +    break;
   }   }
-  return 2; 
 } }
 </code> </code>
  
-Code généré sans les attributs ''%%[[likely]]%%'' et ''%%[[unlikely]]%%''.+===Sur un string=== 
 +''switch'' ne fonctionne sur que les nombres. Pour utiliser un string, il faut passer par une fonction de hash (ici, djb2).
  
-gcc est utilisé et les options d'optimisation doivent être activées au minimum niveau 1.+<code cpp> 
 +constexpr unsigned long djb2(char const *str) 
 +
 +    unsigned long hash = 5381; 
 +    int c = 0;
  
-<code asm> +    while ((c = *str++)
-f(int)+        hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
-  mov     eax, edi +
-  cmp     edi, 1 +
-  je      .L2 +
-  cmp     edi, 2 +
-  mov     edx, 3 +
-  cmovne  eax, edx +
-.L2: +
-  ret +
-</code>+
  
-Code généré avec les attributs ''%%[[likely]]%%'' et ''%%[[unlikely]]%%''.+    return hash; 
 +}
  
-<code asm> +int main() 
-f(int): +{ 
-  mov     eax, edi +  std::string texte = "texte"; 
-  cmp     edi, 1 +  switch (djb2(texte.c_str())) 
-  je      .L2 +  { 
-  cmp     edi, 2 +    case djb2("texte")
-  jne     .L8 +      texte = "OK"; 
-.L2+      break; 
-  ret +  } 
-.L8: +}
-  mov     eax, 3 +
-  ret+
 </code> </code>
 +
 +<WRAP center round important 60%>
 +Toute création d'un hash présente un risque de collision.
 +</WRAP>
 +
lang/cpp/condition.1581917508.txt.gz · Dernière modification : 2020/02/17 06:31 de root