Extensions du langage
Cette page décrit les extensions non K&R du langage C généralement acceptées et intégrées de manière optionnelle à PC-Lint. Ces fonctionnalités sont incluses dans la nouvelle norme ANSI C (bientôt disponible) et sont prises en charge par de nombreux compilateurs.
Le type void
De nombreux compilateurs prennent en charge le type void (même s'il ne figure pas dans la norme K&R). Le type de données void est un mot réservé (sauf si l'option -fvo est définie) et est traité conformément à la nouvelle norme C. Les fonctions déclarées comme void sont considérées comme ne retournant aucune valeur. Toute incohérence à cet égard, que ce soit au niveau des instructions return ou des appels, est signalée. Un pointeur vers void est considéré comme un pointeur universel, c'est-à-dire qu'il peut être affecté ou comparé librement à n'importe quel autre pointeur sans générer d'erreur. Enfin, pour appeler une fonction qui retourne une valeur afin d'obtenir uniquement ses effets de bord, on peut la faire précéder d'une conversion de type void, comme ceci :
- (void) f();
L'option `fvo` permet de supprimer le type `void`.
Conseil utile : Si votre compilateur ne prend pas en charge le type `void`, vous pouvez envisager une définition comme celle-ci :
- #ifdef _lint
- #define CALL (void) /* réduire les peluches */
- #else
- #define CALL
- #endif
que vous utiliseriez comme :
- CALL f();
si vous ne vous intéressiez qu'aux effets de bord d'une fonction.
Prototypes de fonctions
Les déclarations de fonctions peuvent contenir, entre parenthèses, des informations de type indiquant le nombre et les types attendus des arguments. Notez que cela ne s'applique pas aux définitions de fonctions fournissant (comme précédemment) une liste de noms de paramètres entre parenthèses. Par exemple :
indique que la fonction status n'attend aucun argument. Si le mot clef void avait été omis, aucune information de type de paramètre n'aurait été déduite.
Énumération
Le type de données enum est pris en charge par PC-Lint. Cette description suppose une connaissance de base de cette fonctionnalité.
Un type de données énuméré doit d'abord être déclaré; par exemple :
- enum primary { red = 1, yellow, blue };
Un type énuméré nommé «primary» a été déclaré. Ce type est ensuite utilisé pour définir des objets de données énumérés, comme suit :
- enum primary x, *px;
Enfin, ces objets de données peuvent être utilisés. Leur utilisation se limite généralement à l'affectation, au passage d'arguments et aux tests d'égalité.
Les types énumérés sont traités selon deux niveaux : strict et souple. Dans le modèle strict, les valeurs de type énuméré ne peuvent être affectées qu'à des variables, passées en paramètres ou comparées qu'à des valeurs du même type énuméré. Au niveau souple, modèle proposé par la norme ANSI C, une valeur de type énuméré est considérée sémantiquement comme un entier. Elle peut être utilisée dans tout contexte attendant un entier et les variables de type énuméré peuvent se voir affecter n'importe quelle valeur entière. Au niveau strict, cela n'est possible qu'à l'aide de conversions de type.
Par exemple :
- enum food { pear, bread, milk } food1, food2;
-
- food1 = pear;
- food1 = 25;
- food2 = food1 + 1;
- food2 = (enum food) ( (int) food1 + 1 );
Dans l'interprétation souple (modèle entier), les quatre instructions d'affectation sont correctes. Dans le modèle strict, les deuxième et troisième instructions sont signalées. La quatrième représente la modification apportée à la troisième pour la rendre conforme au modèle strict.
Le niveau de rigueur est contrôlé par l'indicateur `+/-fie` (énumérations du modèle entier). Par défaut, cet indicateur est désactivé, ce qui correspond au modèle strict.
signed
Si les données de type caractère ne sont pas signées par défaut (voir l'indicateur +fcu), alors, pour obtenir un octet signé, vous devez utiliser le mot réservé «signed» comme dans :
- signed char x;
«signed», un mot réservé dans ANSI C, n'apparaît pas dans K&R C.