IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

Code C++, MISRA et Cpptest


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 34
    Par défaut Code C++, MISRA et Cpptest
    Bonjour,

    J'ai pour mission de passer Cpptest (de Parasoft) sur un code (que je n'ai pas écrit) afin de vérifier sa compatibilité avec un certain nombre de règles MISRA.
    Alors, soit le module Cpptest n'est pas au moins, soit un truc m'échappe mais j'ai l'impression de tourner en rond.

    J'utilise une fonction qsort personnalisée à laquelle je ne peux toucher (et il n'est pas question de ne pas appeler cette fonction). Cette fonction a pour prototype :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void mon_qsort (void *tableau,
                    size_t nb_elem,
                    size_t taille_elem,
                    mon_int (*compare) (const void *, const void *));
    Je l'utilise de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    mon_qsort((void *)mon_tableau,
              (size_t) nombre_elements,
              (size_t) taille_elem,
              (mon_int (*) (const void *, const void *))ma_comparaison);
    Le code de la fonction ma_comparaison est le suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    mon_int ma_comparaison(const ma_structure * const i_pa, const ma_structure * const i_pb)
    {
      mon_int resultat;
     
      if (i_pa->valeur > i_pb->valeur)
      {
        resultat = -1;
      }
      else  if (i_pa->valeur < i_pb->valeur)
      {
        resultat = 1;
      }
      else
      {
        resultat = 0;
      } 
     
      return resultat;
    }
    Quand je passe Cpptest, j'ai une erreur MISRA sur le qsort, en particulier pour la quatrième entrée :
    "MISRA2008-5_2_6 : Do not convert a pointer to function 'ma_comparaison' to any other pointer type".

    Qu'à cela ne tienne, je décide de faire quelques petits changement. L'appel à mon_qsort devient :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    mon_qsort (void *)mon_tableau,
              (size_t) nombre_elements,
              (size_t) taille_elem,
               ma_comparaison);
    et ma fonction de comparaison est modifiée de la façon suivante. Si je n'ai plus d'erreur MISRA sur le qsort, j'en ai dans mon code maintenant (que je mets en commentaires) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    mon_int ma_comparaison(const void * const i_pa, const void * const i_pb)
    {
      mon_int resultat;
      const ma_structure * const pa = static_cast<const ma_structure *>(i_pa); //MISRA2008-5_2_8 : do not convert pointer to void type to an object pointer type 'const mon_namespace::ma_structure *'
      const ma_structure * const pb = static_cast<const ma_structure *>(i_pb); //MISRA2008-5_2_8 : do not convert pointer to void type to an object pointer type 'const mon_namespace::ma_structure *'
     
      if (pa->valeur > pb->valeur)
      {
        resultat = -1;
      }
      else  if (pa->valeur < pb->valeur)
      {
        resultat = 1;
      }
      else
      {
        resultat = 0;
      } 
     
      return resultat;
    }
    Pas spécialement convaincu, je change les static_cast en dynamic_cast.
    Mes erreurs MISRA disparaissent pour laisser place à d'autres... absolument incompréhensibles à mes yeux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    mon_int ma_comparaison(const void * const i_pa, // MISRA2008-0_1_11 : Parameter 'i_pa' is not used.
                           const void * const i_pb) // MISRA2008-0_1_11 : Parameter 'i_pb' is not used.
    {
      mon_int resultat;
      const ma_structure * const pa = dynamic_cast<const ma_structure *>(i_pa); //MISRA2008-01_3_a : Local variable 'pa' declared but not used
                                                                                //MISRA2008-01_3_b : Local variable 'pa' declared but not used
      const ma_structure * const pb = dynamic_cast<const ma_structure *>(i_pb); //MISRA2008-01_3_a : Local variable 'pb' declared but not used
                                                                                //MISRA2008-01_3_b : Local variable 'pb' declared but not used
     
      [...]
    }
    Comment peut-il dire que les paramètres et variables ne sont pas utilisés ???
    Cpptest est-il fiable, comme outil.

    Y a-t-il un moyen de faire autrement en gardant l'esprit du code ?

    Merci d'avance pour votre aide.

  2. #2
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Vois avec tes supérieurs et tes clients si le respect de cette règle est plus important que l'utilisation de la fonction.

    PS: std::sort, c'est bien pourtant! (et c'est certainement plus rapide...)
    PPS: dynamic_cast n'a aucun rapport avec ce que tu cherches à faire. Le seul cast valide ici est un static_cast. Sauf que MISRA t'interdit ces manipulations vu que le C++ offre un typage plus fort que le C grâce aux templates. Tu vas te faire bananer sur toutes les conversions de pointeurs par MISRA C++. Donc soit ton client veut absolument la conformité à MISRA C++, plus de perfs, et plus de stabilité et tu pars sur std::sort, soit vous réussissez à lui vendre une fonction héritée du C dans un contexte C++ et vous obtenez une dérogation du client.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 34
    Par défaut Code C++, MISRA et Cpptest
    Citation Envoyé par Luc Hermitte Voir le message
    Vois avec tes supérieurs et tes clients si le respect de cette règle est plus important que l'utilisation de la fonction.
    Dans la mesure où la fonction est une fonction validée déjà prête à utilisation car portée sur cible, on ne va pas en changer (j'aurais peut-être dû préciser que c'était destiné à être porté en temps réel).


    Citation Envoyé par Luc Hermitte Voir le message
    PPS: dynamic_cast n'a aucun rapport avec ce que tu cherches à faire. Le seul cast valide ici est un static_cast.
    D'accord, mais pourquoi ? J'avoue que j'ai un peu du mal à saisir la nuance. Le static_cast, si j'ai bien compris, vérifie que c'est valable à la compilation alors que le dynamic_cast le fait à l'exécution, mais si tu pouvais m'expliquer pourquoi le static_cast est le SEUL valable, je crois que je me coucherai moins bête ce soir.

    Citation Envoyé par Luc Hermitte Voir le message
    Sauf que MISRA t'interdit ces manipulations vu que le C++ offre un typage plus fort que le C grâce aux templates.
    C'est un code hérité d'un code C. C'est un peu bâtard, je le conçois.
    MISRA n'aurait pas râlé si j'avais fait un cast classique (monpointeur *) si c'était du C pur ?

    Merci pour les réponses, en attendant.

  4. #4
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Dans la mesure où la fonction est une fonction validée déjà prête à utilisation car portée sur cible, on ne va pas en changer (j'aurais peut-être dû préciser que c'était destiné à être porté en temps réel).
    Je comprends le côté validé. Pour le côté temps-réel, une fois de plus, std::sort a des chances non négligeables d'être plus rapide, mais elle risque d'impliquer un embonpoint supérieur du binaire si la fonction de tri était employée avec plusieurs types de tableaux.

    si tu pouvais m'expliquer pourquoi le static_cast est le SEUL valable, je crois que je me coucherai moins bête ce soir.
    Pour comprendre les divers casts: https://www.developpez.net/forums/d9...p/#post5210670

    C'est un code hérité d'un code C. C'est un peu bâtard, je le conçois.
    MISRA n'aurait pas râlé si j'avais fait un cast classique (monpointeur *) si c'était du C pur ?
    Les règles qui coincent sont des règles de MISRA-C++ parce que l'on sait peut écrire du code plus robuste en C++ grâce aux templates. Donc effectivement, si tu n'appliques que MISRA-C, parce que le code serait alors uniquement en C, il n'y aura pas de problème.


    Mais je le rappelle, la bonne démarche n'est pas de triturer le code pour que ça passe comme par magie sans que l'on ne sache pourquoi (le but des règles MISRA est aussi de combattre la magie des étoiles). C'est de se dire à un moment donné : c'est comme ça que l'on veut procéder et on veut, main dans la main avec le client, qu'il valide notre choix avec une dérogation qu'il nous concèdera officiellement. Un client peut tout à fait comprendre la notion de faux positif. Si vous êtes sur de l'embarqué où le C est une tradition, il acceptera. Et surtout s'il vous a fait signer l'utilisation de MISRA-C++, c'est le seul qui puisse décoincer la situation: soit la conformité à un ensemble de règles, soit l'utilisation d'une fonction estampillée OK par XXX.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  5. #5
    Expert confirmé

    Avatar de dragonjoker59
    Homme Profil pro
    Software Developer
    Inscrit en
    Juin 2005
    Messages
    2 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Software Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 2 033
    Billets dans le blog
    12
    Par défaut
    Les mêmes règles existent en MISRA C, il y a cette règle:
    Rule 11.5

    A conversion should not be performed from pointer to void into pointer to object
    Que tu auras donc si tu tu utilises la norme MISRA C, et la même règle pour la conversion de fonction:
    Rule 11.1

    Conversions shall not be performed between a pointer to a function and any other type
    La seule conversion de pointeur autorisée si je ne me trompe est la conversion vers void *
    Si vous ne trouvez plus rien, cherchez autre chose...

    Vous trouverez ici des tutoriels OpenGL moderne.
    Mon moteur 3D: Castor 3D, presque utilisable (venez participer, il y a de la place)!
    Un projet qui ne sert à rien, mais qu'il est joli (des fois) : ProceduralGenerator (Génération procédurale d'images, et post-processing).

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 34
    Par défaut Code C++, MISRA et Cpptest
    Citation Envoyé par dragonjoker59 Voir le message
    La seule conversion de pointeur autorisée si je ne me trompe est la conversion vers void *
    En fait, j'ai fini par comprendre que quand on a un void *, MISRA ne veut pas qu'on le transtype explicitement.
    Par exemple, avec calloc ou malloc, il faut faire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int * p = malloc(n * sizeof(int));
    et non pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int * p = (int *)malloc(n * sizeof(int));
    Là, j'avoue, je tombe un peu des nues, ça va à l'encontre de tout ce qu'on m'a appris ("point de transtypage implicite ne feras").

  7. #7
    Membre actif
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    34
    Détails du profil
    Informations personnelles :
    Âge : 48
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 34
    Par défaut Code C++, MISRA et Cpptest
    Citation Envoyé par Luc Hermitte Voir le message
    Merci pour le lien.


    Citation Envoyé par Luc Hermitte Voir le message
    Les règles qui coincent sont des règles de MISRA-C++ parce que l'on sait peut écrire du code plus robuste en C++ grâce aux templates. Donc effectivement, si tu n'appliques que MISRA-C, parce que le code serait alors uniquement en C, il n'y aura pas de problème.
    Encore que...

    Citation Envoyé par Luc Hermitte Voir le message
    Mais je le rappelle, la bonne démarche n'est pas de triturer le code pour que ça passe comme par magie sans que l'on ne sache pourquoi (le but des règles MISRA est aussi de combattre la magie des étoiles). C'est de se dire à un moment donné : c'est comme ça que l'on veut procéder et on veut, main dans la main avec le client, qu'il valide notre choix avec une dérogation qu'il nous concèdera officiellement. Un client peut tout à fait comprendre la notion de faux positif. Si vous êtes sur de l'embarqué où le C est une tradition, il acceptera. Et surtout s'il vous a fait signer l'utilisation de MISRA-C++, c'est le seul qui puisse décoincer la situation: soit la conformité à un ensemble de règles, soit l'utilisation d'une fonction estampillée OK par XXX.
    C'est un peu plus compliqué que ça : je suis parachuté sur un code que je n'ai pas écrit pour faire passer MISRA dessus et montrer qu'il est grosso modo MISRA-compatible. Par contre, il n'est plus temps de tout réécrire de zéro. Donc on corrige ce qui à l'évidence à été écrit parfois de manière un peu légère pour renforcer les vérifications de sécurité mais on ne repart pas à zéro. Quant au client, je ne suis même pas sûr qu'il comprenne beaucoup dès lors qu'on rentre dans les détails.

    Néanmoins, au-delà de ces problèmes, je souhaitais savoir si certains avaient déjà eu affaire à CppTest. Parce que dans ma boîte, ça semble être une religion... Mais quand je vois CppTest me conseiller de passer une variable affectée à droite et à gauche en const ou qu'il me dit qu'un paramètre n'est pas utilisé contre toute évidence, j'avoue que la confiance que j'ai dans cet outil en prend un sérieux coup.

    Merci quand même pour les réponses.

  8. #8
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    cpptest comme beaucoup d'autres outils pre-clang n'ont pas une compréhension parfaite du code source. Il est donc classique d'assister à des mauvaises interprétations.
    Ici, en revanche, la faute n'est pas du fait de l'outil.
    (Quand je dis pré-clang, c'est à cause de ce genre de choses que l'on doit à clang: https://github.com/rettichschnidi/clang-tidy-misra -- pas testé, je ne sais donc pas ce qu'il vaut pour passer les règles MISRA)

    Pour les deux exemples à coup de malloc. Le premier est du C valide, mais ne compilera pas en C++. Ici, la solution serait new[], ou mieux, un type tel que std::vector<>, voire dynarray (boost ou c++17?) si on n'a pas besoin de redimensionner dynamiquement le tableau.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. De la rapidité du code
    Par jfloviou dans le forum Contribuez
    Réponses: 233
    Dernier message: 29/05/2009, 02h17
  2. code pour interbase 6.0 et 6.5 de generateur
    Par tripper.dim dans le forum InterBase
    Réponses: 4
    Dernier message: 01/07/2002, 11h29
  3. [MFC](encapsulation ADO) ou placer le code
    Par philippe V dans le forum MFC
    Réponses: 2
    Dernier message: 13/06/2002, 14h58
  4. Explorateur de code C
    Par Zero dans le forum C
    Réponses: 14
    Dernier message: 06/06/2002, 09h41
  5. OmniORB : code sous Windows et Linux
    Par debug dans le forum CORBA
    Réponses: 2
    Dernier message: 30/04/2002, 17h45

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo