3

Nous écrivons du code dans le noyau Linux, donc, comme je le faisais, je n'ai pas réussi à faire fonctionner PC-Lint/Flexelint sur le noyau Linux. Juste trop de symboles intégrés, etc. Mais c'est un problème secondaire.Catching débordement du décalage gauche de la constante 1 en utilisant l'avertissement du compilateur?

Nous avons un certain nombre de compilateurs, en commençant par gcc, mais d'autres également. Leurs options d'alertes se sont renforcées au fil du temps, où elles sont aussi des outils d'analyse statique assez puissants.

Voici ce que je veux attraper. Oui, je sais que cela viole certaines choses qui sont faciles à repérer dans la révision de code, comme "pas de nombres magiques", et "méfiez-vous des changements de bits", mais seulement si vous regardez cette section du code. Quoi qu'il en soit, le voici:

unsigned long long foo; 
unsigned long bar; 

[... lots of other code ...] 

foo = ~(foo + (1<<bar)); 

Description du problème encore à jour - même avec une barre limitée à 16, toujours un problème. Pour clarifier, le problème est implicite dans le type de constante qui, non planifié, fait que l'expression complexe viole la règle selon laquelle tous les calculs doivent être effectués avec la même taille et la même signature.

Problème: '1' n'est pas long, mais, en tant que constante de petite valeur, vaut int. Par conséquent, même si la valeur réelle de la barre ne dépasse jamais, par exemple, 16, l'expression (1<<bar) débordera et ruinera tout le calcul.

Solution éventuellement correcte: écrire 1ULL à la place.

Existe-t-il un indicateur d'avertissement de compilateur et de compilateur bien connu qui signalera ce problème (révisé)?

+0

Quelle que soit la taille int, si la barre est trop grande, le décalage est indéfini (je pense, une sorte de mauvais, de toute façon). Vous semblez demander au compilateur de vous avertir d'un deuxième opérande variable à déplacer sur un int. Mais vous dites que le problème est que '1' n'est pas long: vous ne voulez pas d'avertissement sur un décalage variable sur une longue période? Je ne vois pas pourquoi les compilateurs-rédacteurs s'attendraient à ce que cet avertissement soit utile, et les avertissements généraux concernant la deuxième opérande variable à << entraîneraient un grand nombre de faux positifs. –

+0

@onebyone: En supposant que 'int' est 32 bits et' long long' est 64, '~ (foo + (1 << bar))' ne fonctionne que pour '0 <= bar <32', alors que' ~ (foo + (1LL << bar)) 'fonctionne pour' 0 <= bar <64'. Je suppose que OP veut un avertissement quand le premier est écrit au lieu du dernier. – ephemient

+0

Bien sûr, mais voudrait-il cet avertissement dans les cas où foo est un int et que la barre est logiquement contrainte (mais pas par type) à être 1 ou 2? Que diriez-vous où foo est long et la barre est 1 ou 2? Avertissements pour multiplier ou ajouter une barre à toute constante signée, puisque le résultat du débordement est indéfini?Le compilateur ne peut généralement pas identifier les contraintes logiques, donc je m'attends à ce que de tels avertissements soient fortement sujets aux faux positifs. Cela ne veut pas dire que c'est une mauvaise idée, je ne fais que spéculer pourquoi il est difficile de définir ce qu'il devrait être, et de toute façon une faible priorité pour les rédacteurs de compilateurs. –

Répondre

1

Je ne suis pas sûr de ce que les critères que vous envisagez de signaler cette construction comme suspect. Il est clairement quelque chose de mal si la valeur de la barre est aussi grande que la taille (en bits) d'un int, mais généralement le compilateur ne le sait pas. Du point de vue d'un heuristique, outil de recherche de bug, ayant de bons motifs pour séparer les bugs probables de constructions normales est la clé pour éviter trop de faux positifs (qui font que les utilisateurs détestent l'outil et refusent l'utiliser) .

L'Open outil Source dans mes drapeaux d'URL des changements logiques par un plus grand nombre que la taille du type, mais il est avant tout un outil de vérification pour les logiciels embarqués critiques et attendent beaucoup de travail à elle approprié si vous l'intention de l'utiliser sur le noyau Linux avec ses structures liées et d'autres difficultés.

+0

Je vais regarder votre site web, je me suis rendu compte qu'en suggérant la barre à 64, j'ai induit en erreur. Même à ce moment-là, il y a un problème, ce que la charpie attrape, mais je cherche à attraper gcc.Le problème n'est pas le trop-grand-shift, en soi, c'est l'expression complexe avec, involontairement, plusieurs types. – talkaboutquality

Questions connexes