Partage
  • Partager sur Facebook
  • Partager sur Twitter

Code portable

    12 décembre 2018 à 13:49:23

    Hello world ! Excusez moi de vous dérangé, mais j'ai une question au sujet des types de données définies dans stdint.h (int8_t, uint8_t, int32_t, ...). J'ai lu beaucoup de choses dessus, mais les avis divergent, certains disant d'utiliser ces types à tout pris, d'autre arquant que c'est n'importe quoi...

    Dans le cas ou je développe une bibliothèque multiplateforme, utilisant le réseau et la cryptographie (Donc nécessité de conserver la taille des types d'une machine à une autre), suis-je censé utiliser les types de stdint.h ou les types de bases (char, unsigned char, int, ...) ? Sachant que la bibliothèque doit également fournis des fonctions de manipulation des chaînes, qui s'appuient elles-même sur les fonctions de la bibliothèque standard (strdup(), strcmp(), ...)...

    Merci de vos réponse par avance !

    • Partager sur Facebook
    • Partager sur Twitter
      12 décembre 2018 à 14:09:04

      Salut,

      Il me semble que ces types sont standard depuis un moment. Mais si tu compiles sur de vieeeeux compilos, ça ne passera pas.

      Dans le doute, tu peux te faire tes propres types. Par exemple, SDL définit Uint32, Uint8 etc...

      Et c'est juste des typedef, comme ça le jour ou ça ne marche pas sur une plateforme, tu n'as qu'à changer le typedef et juste ça.

      Mais tu peux aussi utiliser stdint.h, et si un jour un compilo gueule parce que tu ne l'as pas, tu en fais un pour ce compilo la en mettant les bons typedef dedans.

      • Partager sur Facebook
      • Partager sur Twitter

      Recueil de code C et C++  http://fvirtman.free.fr/recueil/index.html

        12 décembre 2018 à 14:18:27

        TomAnderson1 a écrit:

        Dans le cas ou je développe une bibliothèque multiplateforme, utilisant le réseau et la cryptographie (Donc nécessité de conserver la taille des types d'une machine à une autre), suis-je censé utiliser les types de stdint.h ou les types de bases (char, unsigned char, int, ...) ? Sachant que la bibliothèque doit également fournis des fonctions de manipulation des chaînes, qui s'appuient elles-même sur les fonctions de la bibliothèque standard (strdup(), strcmp(), ...)...

        Merci de vos réponse par avance !

        Bonjour,

        Si tu as besoin de types d'un nombre précis de bits, il faut évidemment utiliser les types de <stdint.h>. Pour les autres types (pour les chaines de caractères, les tailles de tableu, les statut de fonction, etc.) utilise les types des bibliothèques que tu utilises.

        Rien que la bibliothèque standard fourni déjà des exemples tout à fait éclairant:

        size_t strlen(const char *);
        void *memset(void *, int, size_t);
        void *malloc(size_t);
        size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

        Mais le mieux est encore de lire la documentation de ces types:

        http://pubs.opengroup.org/onlinepubs/7908799/xsh/stddef.h.html

        ptrdiff_t
        Signed integral type of the result of subtracting two pointers.
        wchar_t
        Integral type whose range of values can represent distinct wide-character codes for all members of the largest character set specified among the locales supported by the compilation environment: the null character has the code value 0 and each member of the Portable Character Set has a code value equal to its value when used as the lone character in an integer character constant.
        size_t
        Unsigned integral type of the result of the sizeof operator.


        Lis aussi http://pubs.opengroup.org/onlinepubs/009695399/basedefs/stdint.h.html.

        -
        Edité par Marc Mongenet 12 décembre 2018 à 14:19:07

        • Partager sur Facebook
        • Partager sur Twitter
          12 décembre 2018 à 14:27:06

          Merci de vos réponses ! Mais y a un truc que je comprend pas: "Si tu as besoin de types d'un nombre précis de bits, il faut évidemment utiliser les types de <stdint.h>. Pour les autres types (pour les chaines de caractères, les tailles de tableu, les statut de fonction, etc.) utilise les types des bibliothèques que tu utilises."

          Si ces types sont définis, ce ne sont que de simple typedef. Donc on devrais très bien pouvoir utiliser int8_t par exemple, partout dans son code, incluant le passage d'arguments aux fonctions de la bibliothèque standard, non ?

          -
          Edité par TomAnderson1 12 décembre 2018 à 14:29:55

          • Partager sur Facebook
          • Partager sur Twitter
            12 décembre 2018 à 17:51:03

            TomAnderson1 a écrit:

            Merci de vos réponses ! Mais y a un truc que je comprend pas: "Si tu as besoin de types d'un nombre précis de bits, il faut évidemment utiliser les types de <stdint.h>. Pour les autres types (pour les chaines de caractères, les tailles de tableu, les statut de fonction, etc.) utilise les types des bibliothèques que tu utilises."

            Si ces types sont définis, ce ne sont que de simple typedef. Donc on devrais très bien pouvoir utiliser int8_t par exemple, partout dans son code, incluant le passage d'arguments aux fonctions de la bibliothèque standard, non ?

            -
            Edité par TomAnderson1 il y a environ 3 heures

            Je ne comprends pas très bien ta question.
            Mais admettons que ta bibliothèque contient une fonction qui traite un tableau d'octets non signés, alors son prototype devrait être:

            #include <stddef.h>
            #include <stdint.h>
            
            void my_func(uint8_t *arr, size_t size);
            

            Si l'on fait du code propre et portable, il faut utiliser le type uint8_t pour représenter un octet non signé, et il faut utiliser le type size_t pour représenter une taille de tableau.

            -
            Edité par Marc Mongenet 12 décembre 2018 à 17:52:42

            • Partager sur Facebook
            • Partager sur Twitter
              13 décembre 2018 à 7:22:27

              Je veux dire qu’apparemment il est recommandé d'utiliser les mêmes types que les bibliothèques qu'on utilise. Par exemple pour travailler avec les fonctions de string.h, il faut utiliser char. Pas int8_t (C'est comme ca que j'ai compris le post). Mais comme les types de stdint.h sont de simples typedef, pourquoi on ne peux pas les utiliser partout ?

              Après, si vous savez comment figer les données pour le transfert d'une machine à une autre, aussi bien par le réseau que par échange de fichiers, ca me va... (Je préfère utiliser les types de base personnellement)

              • Partager sur Facebook
              • Partager sur Twitter
                13 décembre 2018 à 10:15:07

                TomAnderson1 a écrit:

                Je veux dire qu’apparemment il est recommandé d'utiliser les mêmes types que les bibliothèques qu'on utilise. Par exemple pour travailler avec les fonctions de string.h, il faut utiliser char. Pas int8_t (C'est comme ca que j'ai compris le post). Mais comme les types de stdint.h sont de simples typedef, pourquoi on ne peux pas les utiliser partout ?

                Après, si vous savez comment figer les données pour le transfert d'une machine à une autre, aussi bien par le réseau que par échange de fichiers, ca me va... (Je préfère utiliser les types de base personnellement)


                Techniquement, on peut utiliser les types de <stdint.h> partout. Enfin, tant que le typedef existe sur le système cible, ce qui est généralement le cas, mais pas garanti.

                Mais prenons le cas d'un tableau, quel type utiliser pour l'indice? La norme du langage nous garanti que le type size_t est approprié pour cela. Le type unsigned int est-il aussi approprié? On ne sait pas, il peut être trop court. Le type unsigned long est-il aussi approprié? On ne sait pas, il peut être innefficace. Il n'y a que size_t pour lequel on a une garantie. Et c'est évidemment pour cela qu'on retrouve size_t dans toutes les fonctions standards où il y a une notion de dimension d'objet (strlen, malloc, fread...)

                -
                Edité par Marc Mongenet 13 décembre 2018 à 10:15:49

                • Partager sur Facebook
                • Partager sur Twitter
                  13 décembre 2018 à 11:56:07

                  Salut !

                  stdint.h est un des nombreux fichiers d'en-tête de la bibliothèque standard C.

                  Cette bibliothèque est fournie par tous les OS et mise à jour dès qu'une nouvelle norme ISO passe.

                  Généralement les MAJ ajoutent des fonctions/types sans en enlever donc ces types resteront actifs.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    13 décembre 2018 à 15:56:43

                    La portabilité c'est utiliser le bon type au bon moment. Exemples :

                    N'utiliser les types uint8_t int8_t uint16_t int16_t uint32_t int32_t uin64_t int64_t que si on a besoin de cette taille exacte pour interagir avec un module externe qui nous impose cette taille. Exemple : certains processeurs ne peuvent pas gérer le uint8_t tel  que le MSP320, un code qui les utilise ne compilera plus.

                    Pour les passage de paramètres et les variables locales, il faut préférer les types int_fast8_t, uint_fast8_t, .... qui garantissent d'être assez grands pour la taille demandée et sont optimums en vitesse. Exemple : certains processeurs ARM gèrent difficilement les données 16bits, pour eux uint_fast16_t fait 32 bits.

                    Les types int_least8_t, uint_least8_t sont eux utiles dans des structures. Il garantissent d'être assez grands pour la taille demandée, tout en étant plus économiques en mémoire que leur homologues 'fast'. Ainsi pour le MSP320 qui n'a pas d'octets, le type int_least8_t fait 16 bits.

                    Utiliser les type char ou wchar en fonction du besoin (par exemple char pour caractères ASCII ou UTF8, et wchar pour les chaines de caractères utilisateur.

                    Utiliser quand c'est nécessaire les types types size_t (pour les tailles d'objet ou nombre d'élément), intptr_t intmax_t uintptr_t (garanti assez grand pour un int ou un pointeur.) et uintmax_t (le plus grand nombre arithmétique).

                    Le type int n'est pas à oublier, il est le champion pour les variables locales et les paramètres.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    En recherche d'emploi.

                      13 décembre 2018 à 18:12:21

                      Merci pour toutes ces réponses !

                      En fait je ne comprend pas pourquoi ne pas faire systématiquement ça: "Techniquement, on peut utiliser les types de <stdint.h> partout. Enfin, tant que le typedef existe sur le système cible, ce qui est généralement le cas, mais pas garanti.", alors que si on les utilise une seule fois, on sait déjà que le code ne compilera pas sur toutes les plateformes...

                      Dalfab, je voulais utiliser ces types pour gagner en portabilité. Si j'utilise int_fast8_t, par exemple, à la place, ça ne présente plus d’intérêt, dans la mesure où certes, il sera assez grand, mais pas forcement transférable d'une machine à une autre ! Pour reprendre ton exemple du MSP320, que je ne connais absolument pas, comment enverrai-tu une chaîne de caractères d'une machine avec ce processeur, en t'assurant que les données soit valides à l'arrivé ?

                      Je sais pas si je suis clair...

                      • Partager sur Facebook
                      • Partager sur Twitter

                      Code portable

                      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                      • Editeur
                      • Markdown