la raison derrière Misra 2012 ne permet pas de transtyper entre différents pointeurs

Je travaille actuellement sur un projet nécessitant que le code soit conforme à Misra 2012. Tout au long du projet, nous avons reçu un grand nombre d’avertissements misra obligatoires nous indiquant que nous ne pouvons pas convertir le pointeur d’un type à un autre. Des choses aussi simples que void *memcpy(void *to, const void *from, size_t n) produisent deux avertissements Misra Required puisque tous les deux doivent être void *memcpy(void *to, const void *from, size_t n) void * et const void *. La conversion de void * en un pointeur vers un autre type génère également un avertissement Misra.

Ma question est la suivante: comment Misra s’attend-il à ce que malloc et tout le rest fonctionnent sans aucun avertissement? Même en convertissant un tampon * vide en un tampon uint8_t * pour parsingr octet abuffer et octet et remplir tous les éléments d’une structure, la structure émettra de nombreux avertissements?

Au lieu de ces avertissements, ne pourrait-il pas simplement utiliser une note ou des informations nous demandant de vérifier l’emballage, l’alignement et tout ce qui pourrait mal tourner?

J’aimerais revenir à la question posée par le PO et clarifier quelques points. Tout d’abord, l’appel de void * memcpy (void * à, const void * de, size_t n) ne pose aucun problème, car la conversion d’un pointeur en object en pointeur vide ne viole aucune directive de MISRA-C: 2012. En d’autres termes, tout outil produisant des violations pour cela est simplement un buggy.

Deuxièmement, avant de tirer quelque conclusion que ce soit, il est important de lire ce que dit la règle 11.5, la directive pertinente de MISRA-C: 2012, à savoir:

   Règle 11.5
   Une conversion ne doit pas être effectuée d'un pointeur à un autre en
   pointeur vers object

   Avis de catégorie
   Analyse décidable, unité de traduction unique
   S'applique aux C90, C99

   Raisonnement
   La conversion d'un pointeur en néant en un pointeur en object peut entraîner
   dans un pointeur qui n'est pas correctement aligné, résultant en undefined
   comportement.  Cela devrait être évité autant que possible mais peut être nécessaire,
   par exemple lorsqu'il s'agit de fonctions d'allocation de mémoire.  Si
   la conversion d'un pointeur à object en un pointeur à annuler est utilisée,
   il faut veiller à ce que tous les indicateurs produits ne soient pas
   donner lieu au comportement non défini décrit à la règle 11.3.

Observations:

  1. il s’agit d’une règle consultative (c’est-à-dire qu’elle n’est ni obligatoire ni obligatoire), elle peut donc être déviée et MISRA a défini le processus correct de déviation;
  2. convertir un pointeur en object en un pointeur en annulation est acceptable: c’est l’inverse qui pose problème;
  3. la justification mentionne explicitement les fonctions d’allocation de mémoire (et, oui, un programme utilisant l’allocation de mémoire dynamic peut être rendu conforme à MISRA-C: 2012);
  4. la justification fournit des indications sur la marche à suivre pour convertir des pointeurs en objects en points nuls, ce qui est parfaitement conforme à ce que souhaiterait avoir le PO (“informations nous demandant de vérifier une nouvelle fois l’emballage, l’alignement et tout ce qui pourrait mal tourner”).

Cela ne répond pas à votre question, qui concerne les raisons. Au contraire, il indique que vous ne devriez pas être dans cette situation en premier lieu.

Taper “misra malloc” dans votre moteur de recherche préféré nous amène à:

http://www.misra.org.uk/forum/viewtopic.php?t=260

qui demande:

Conformément à la règle, nous ne sums pas censés utiliser des fonctions telles que malloc (), free (), calloc (), etc. Mais malloc () est une exigence très courante. La plupart des applications système intégrées utilisent leurs propres gestionnaires de mémoire au niveau de l’application afin de rendre l’allocation et la désaffectation rapides. Avez-vous des suggestions pour résoudre ce problème (si nous ne pouvons pas utiliser malloc, autrement)?

Et la réponse est:

On nous a demandé des solutions et des solutions de contournement pour diverses choses interdites dans MISRA C1 et MISRA C2 telles que l’utilisation de malloc, calloc, etc. pour l’allocation dynamic de mémoire. Ni la MISRA, ni aucun membre du groupe de travail MISRA C ne donneront de directives ou d’approbation à une déviation ou à une “solution de contournement”.


Vous avez l’obligation que le code se conforme à une certaine norme. Vous utilisez des mécanismes qui ne sont pas conformes à cette norme. Déterminez un moyen solide et fondé sur des principes de vous conformer à la loi ou définissez une politique claire sur la manière de traiter le non-respect délibéré.

Vous mentionnez memcpy, par exemple. C’est non conforme. Alors prenez un peu de recul et demandez “supposons que je n’ai aucune implémentation de memcpy. Comment pourrais-je écrire ma propre memcpy qui était conforme ?” Vous utilisez memcpy pour résoudre un problème; résoudre le problème sans cela.

Maintenant, faites la même chose pour Malloc. Il y avait un jour où malloc n’existait pas, et quelqu’un a dû l’écrire sans malloc. Vous avez un problème qui est résolu par Malloc. Si vous n’aviez pas malloc, comment le résoudriez-vous? Rien dans Malloc n’est magique; vous pouvez écrire votre propre travail qui fait un meilleur travail que malloc, où par “meilleur” je veux dire “se conforme à vos exigences”.

MISRA-C: 2012 est en fait un peu laxiste en matière de conversion de pointeur. La plupart des règles sont saines, car elles vous obligent à suivre le standard C, ne font pas appel à un comportement indéfini, ou font des choses universellement mauvaises, telles que supprimer des qualificateurs de const d’un pointeur. Vous ne devriez avoir aucune objection à cela.

La seule règle controversée est 11.5:

Une conversion ne doit pas être effectuée à partir d’un pointeur à annuler en un pointeur à un object.

Je pense que celui-ci est la cause de la tête. La raison en est l’alignement et les conversions entre types de pointeurs incompatibles, ce qui conduirait à un comportement indéfini.

En effet, cette règle interdit indirectement l’utilisation de nombreuses fonctions de base de la bibliothèque telles que memcpy . Ma recommandation personnelle à la MISRA concernant cette règle lors de l’examen de 2012 était la suivante:

(Fortement en désaccord) “Il y a trop de cas de programmation C générique lorsque des lancers de pointeurs vides sont nécessaires. Cette règle est peu pratique et fera plus de mal que de bien. Définissez plutôt une règle interdisant le danger spécifique que la règle tente de protéger contre , à savoir “pointeur sur x, conversion en vide *, conversion en pointeur vers y”. ”

Mais ils n’ont pas écouté, et voilà: une règle inutile qui oblige chaque outil à cracher un flot de faux positifs. Cela signifie que chaque utilisateur de MISRA doit ignorer cette règle. Il s’agit d’un conseil afin que vous puissiez l’ignorer sans déclencher une procédure de déviation. Bloquez-le simplement dans votre parsingur statique et continuez.

Le comité MISRA n’a pas encore compris que les faux positifs sont un danger pour la sécurité, car cela pourrait amener les gens à réécrire du code parfaitement fin, introduisant ainsi des bugs.

comment Misra s’attend-il à malloc

MISRA s’attend à ce que vous n’utilisiez pas du tout malloc, il est explicitement interdit par la directive 4.12, pour des raisons très sérieuses. Mais c’est un autre sujet.