141 votes

Fonctionnalités cachées de C

Je sais qu'il y a une norme derrière toutes les implémentations de compilateur C, donc il ne devrait y avoir aucune fonctionnalité cachée. Malgré cela, je suis sûr que tous les développeurs C ont des astuces cachées/secrètes qu'ils utilisent tout le temps.

116voto

tonylo Points 2058

Plutôt un tour de passe-passe du compilateur GCC, mais vous pouvez donner des indications d'indice de branche au compilateur (courant dans le noyau Linux)

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)

voir : http://kerneltrap.org/node/4705

Ce que j'aime à ce sujet, c'est qu'il ajoute également de l'expressivité à certaines fonctions.

void foo(int arg)
{
     if (unlikely(arg == 0)) {
           do_this();
           return;
     }
     do_that();
     ...
}

77voto

Ben Collins Points 11318
int8_t
int16_t
int32_t
uint8_t
uint16_t
uint32_t

Ce sont un élément facultatif dans la norme, mais cela doit être une fonctionnalité cachée, car les gens les redéfinissent constamment. Une base de code sur laquelle j'ai travaillé (et que je travaille encore, pour l'instant) a plusieurs redéfinitions, toutes avec des identifiants différents. La plupart du temps, c'est avec des macros préprocesseur:

#define INT16 short
#define INT32  long

Et ainsi de suite. Ça me donne envie de m'arracher les cheveux. Utilisez simplement les typedefs entiers standard!

73voto

Ben Collins Points 11318

L'opérateur de virgule n'est pas largement utilisé. Il peut certainement être mal utilisé, mais il peut aussi être très utile. Cette utilisation est la plus courante :

for (int i=0; i<10; i++, doSomethingElse())
{
  /* whatever */
}

Mais vous pouvez utiliser cet opérateur n'importe où. Observez :

int j = (printf("Assignation de la variable j\n"), getValueFromSomewhere());

Chaque instruction est évaluée, mais la valeur de l'expression sera celle de la dernière instruction évaluée.

63voto

mike511 Points 637

initialisation de la structure à zéro

struct mystruct a = {0};

cela mettra tous les éléments de la structure à zéro.

62voto

zvrba Points 14028

Pointeurs de fonction. Vous pouvez utiliser une table de pointeurs de fonction pour implémenter, par exemple, des interprètes de code à enfilage indirect rapide (FORTH) ou des dispatchers de bytecode, ou pour simuler des méthodes virtuelles semblables à celles de l'Orienté Objet.

Ensuite, il y a des joyaux cachés dans la bibliothèque standard, tels que qsort(), bsearch(), strpbrk(), strcspn() [ces deux derniers étant utiles pour implémenter un remplacement de strtok()].

Une caractéristique regrettable de C est que le dépassement arithmétique signé est un comportement indéfini (UB). Ainsi, chaque fois que vous voyez une expression telle que x+y, les deux étant des entiers signés, cela pourrait potentiellement causer un dépassement et provoquer un UB.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X