Partage
  • Partager sur Facebook
  • Partager sur Twitter

Les mots clefs du C

Discussion sur le topic sur les mots clefs du C

Anonyme
    18 juillet 2012 à 22:29:57

    Salut à tous,

    Tous les membres inscrits depuis un certain temps qui fréquentent régulièrement le forum C pourront en témoigner : assez régulièrement un topic est créé pour obtenir des explications sur tel ou tel mot-clef. Un topic rassemblant la liste de tous les mots-clefs du C et du C++ est disponible sur le forum C++, mais elle est incomplète (elle ne parle pas des normes C99 et C11), et certaines explications sont vraiment trop courtes ou trop peu précises.

    Le but de ce topic (approuvé par GuilOooo) est que chacun puisse proposer une explication pour un mot-clef du C, peu importe la norme. Il faut simplement que les explications soit suffisamment complètes et surtout correctes. Dès qu'une version est approuvée, elle sera ajoutée au topic "officiel" sur les mots-clefs (topic tenu par GuilOooo). Ainsi, dès qu'un membre posera une question sur un mot-clef, il suffira de l'orienter vers le topic pour qu'il y trouve une réponse correcte et assez complète.

    Pour donner une explication sur un mot-clef, il suffit de poster sur ce topic en utilisant ce modèle :

    <minicode type="c">Mot-clef</minicode>
    
    <gras>Norme</gras> :
    <gras>Description</gras> :
    
    <gras>Exemple et / ou commentaire : </gras>
    


    Merci d'avance à tous pour votre participation,

    informaticienzero
    </span>

    auto break case char const continue default do
    double else enum extern float for goto if
    int long register return short signed sizeof static
    struct switch typedef union unsigned void volatile while
    • Partager sur Facebook
    • Partager sur Twitter
      18 juillet 2012 à 22:53:28

      Là, je n'ai pas le temps, mais je n'ai pas vu nothrow dans la liste
      http://www.cplusplus.com/reference/std/new/nothrow/

      Je ne sais pas si ça peut entrer dans les mots clés mais ^^

      __________________

      http://www.cplusplus.com/reference/clibrary/ciso646/
      Apparemment en C, avec le header, ce sont des macros, mais en C++, ce ne le sont pas..
      Encore une fois, je ne sais pas si on peut les mettre dans la liste ^^'
      • Partager sur Facebook
      • Partager sur Twitter
      perror(const char * str); will save your life !
      Anonyme
        18 juillet 2012 à 23:09:25

        Excellente initiative ! ;)
        Pour les types on en parlera aussi ?

        @Sylar : Faudrait peut être préciser, dans la partie commentaire, qu'il s'agisse des marcos et il faut inclure des headers.
        • Partager sur Facebook
        • Partager sur Twitter
        Anonyme
          18 juillet 2012 à 23:14:49

          Citation : Ouss4

          Excellente initiative ! ;)
          Pour les types on en parlera aussi ?



          Merci. :)
          Oui on parle de tous les mots-clefs du C, donc des types aussi.

          @SylafrsOne : ça existe en C ça ? C'est pas du C89 alors.
          • Partager sur Facebook
          • Partager sur Twitter
          Anonyme
            18 juillet 2012 à 23:20:54

            Pour nothrow c'est du C++.
            On doit rassembler uniquement des mots clefs C, non?

            • Partager sur Facebook
            • Partager sur Twitter
            Anonyme
              18 juillet 2012 à 23:23:21

              Oui c'est ça. Le but est justement de se séparer du topic déjà présent sur le forum C++ pour offrir aux membres un topic complet (tout du moins le plus possible) sur les mots-clefs du C uniquement (et y'a déjà de quoi faire).
              • Partager sur Facebook
              • Partager sur Twitter
                18 juillet 2012 à 23:31:37

                Ah ok, j'avais lu de travers ^^
                Le topic principal pour la liste des mots clés en C est où ?

                On peut déjà ajouter les
                if,else,while,do,for,break,continue,return,goto,
                void,int,char,long,double,float,signed,unsigned,
                case,switch,static,volatile,extern,sizeof,const,
                struct,enum,union,typedef
                


                Les trucs de départ, en somme, qui se trouvent presque partout ^^

                Ensuite il y a asm mais je ne sais pas s'il est dans la norme (je vais regarder C99)
                http://www.codeproject.com/Articles/15 [...] sembly-in-C-C

                Edit :

                Citation

                J.5.10 The asm keyword
                1 The asm keyword may be used to insert assembly language directly into the translator
                output (6.8). The most common implementation is via a statement of the form:
                asm ( character-string-literal );



                En lisant la norme j'ai vu :
                fortran, inline, restrict, auto, register, short, 
                _Bool, _Complex, _Imaginary
                


                Citation

                The LIA−1 data type Boolean is implemented by the C data type bool with values of
                true and false, all from <stdbool.h>.


                ________________

                En plus des keywords, pouvons nous parler des macros (comme offsetof, NULL, RAND_MAX, EXIT_SUCCESS, EXIT_FAILURE) et des directives de préprocesseur ? (#if #endif, etc..)
                • Partager sur Facebook
                • Partager sur Twitter
                perror(const char * str); will save your life !
                Anonyme
                  19 juillet 2012 à 0:00:12

                  C'est GuilOooo qui va le créer. Sinon oui je suis d'accord avec toi, parler de quelques unes des macros est une bonne idée. :)

                  Je m'occupe d'asm.

                  asm

                  Norme : C89 / C99 / C11
                  Description : ce mot-clef est une extension qui permet d'introduire des portions de code en assembleur dans un code source C. La norme ne précise que son comportement, son fonctionnement varie donc selon les compilateurs. Ainsi, ce mot-clef n'est pas portable puisqu'il dépend de l'implémentation.

                  Citation : Norme C89 - A.6.5.10 The asm keyword



                  The asm keyword may be used to insert assembly-language code directly into the translator output. The most common implementation is via a statement of the form

                  asm ( character-string-literal );



                  Ce mot-clef étant une extension, l'utilisation de l'option de compilation -ansi le désactive. Il faut donc utiliser le mot-clef défini par le compilateur choisi.

                  Exemple et / ou commentaire :

                  Avec GCC / MinGW



                  Pour GCC / MinGW, le mot-clef est __asm__. La syntaxe pour l'utiliser est la suivante :

                  __asm__
                  (
                      /* code assembleur */
                  );
                  


                  Assembleur inline basique


                  Avant toute chose, il faut savoir que l'assembleur utilisé par GCC (appelé as ou Gas)utilise la syntaxe AT&T et non la syntaxe Intel. Pour ceux qui ne connaissent pas, une petite liste des différences entre les deux syntaxes a été dressée ici.

                  Les instructions assembleur se déclarent entre guillemets et se terminent par "\n\t", exceptée la dernière. Ces deux caractères permettent de formater correctement le code pour l'envoyer à Gas (l'assembleur de GCC). Il est très fortement recommander de les utiliser. Voici un exemple de code assembleur basique :

                  __asm__
                  (
                       "movl %eax, %ebx\n\t"
                       "movl $56, %esi\n\t"
                       "movb %ah, (%ebx)"
                  );
                  


                  Pour l'instant, c'est assez limité : on ne peut même pas manipuler de variables. C'est là qu'intervient l'assembleur étendu.

                  L'assembleur étendu


                  L'assembleur étendu nous permet de spécifier des opérandes et ainsi manipuler des variables dans notre code assembleur. La syntaxe est la suivante :

                  __asm__
                  (
                      /* instructions assembleur */
                          : opérandes de sortie                               /* optionnel */
                          : opérandes d'entrée                                /* optionnel */
                          : liste des registres "pollués"  ou clobber list    /* optionnel */
                  );


                  Chaque opérande est décrite par une contrainte entre guillemets suivie par une expression en C entre parenthèses. La contrainte sert à décrire où sera stockée la variable en paramètre. Elle peut être parmi la liste suivante :

                  • "r" : dans n'importe quel registre (eax, ebx, etc) ;
                  • "a" : spécifiques aux registres eax, ax et al ;
                  • "b" : spécifiques aux registres ebx, bx et bl ;
                  • "c" : spécifiques aux registres ecx, cx et cl ;
                  • "d" : spécifiques aux registres edx, dx et dl ;
                  • "S" : pour les registres esi et si ;
                  • "D" : pour les registres edi et di ;
                  • "m" : lorsque l'opérateur est dans la mémoire ; on peut donc effectuer des opérations directement sur l'adresse mémoire sans avoir à passer par un registre. Par exemple dans un OS, l'IDT définie par le noyau peut être chargée ainsi :

                    __asm__ ("lidt %0\n" : /* pas de sortie */ :"m"(idt));
                    


                    Cependant, il n'est recommandé d'utiliser cette contrainte que si elle est vraiment nécessaire ou si elle accélère suffisamment le processus.


                  D'autres contraintes sont spécifique à l'architecture x86 :

                  • "f" : pour un registre flottant ;
                  • "t" : pour le premier registre flottant ;
                  • "u" : pour le second registre flottant ;
                  • "q" : registre a, b, c ou d


                  En plus de ces contraintes, il existe également des modificateurs de contrainte :

                  • "=" : signifie que l'opérande est en écriture seule pour cette instruction, la valeur précédente est éliminée et remplacée par des données de sortie. Ce modificateur est utilisé pour les opérandes de sortie.
                  • "&" : signifie que l'opérande sera modifiée avant la fin de la fonction. Il est utilisé quand on fait une boucle par exemple.
                  • "=&" : c'est la combinaison des deux précédents.


                  Le troisième paramètre est quant à lui la liste des registres utilisés dans le code assembleur sans compter les opérandes d'entrée et de sortie. Elle permet d'indiquer à GCC que nous gérons nous-mêmes ces registres. Ainsi, GCC ne vérifiera pas si la valeur chargée dans ces registres est valide. Par contre, GCC connait les registres utilisés par les opérandes d'entrée et de sortie, il ne faut donc pas les préciser.

                  Il est temps de tout récapituler par un exemple. Prenons ce code qui additionne deux variables.

                  int main(void)
                  {
                      int foo = 10, bar = 15;
                      
                      __asm__
                      (
                          "addl %%ebx, %%eax"
                              : "=a"(foo)
                              : "a"(foo), "b"(bar)
                      );
                          
                      printf("foo + bar = %d\n", foo);
                      return 0;
                  }
                  


                  On demande dans cette exemple de stocker la variable foo dans le registre eax ("a"(foo)), et la variable bar dans le registre ebx ("b"(bar)), puis on demande d'additionner les deux registres et de stocker le résultat dans la variable foo ("=a"(foo)). On remarque ici que la liste des registres pollués n'est pas précisée puisque les deux registres utilisés sont déjà connus d'avance par GCC, car ils sont utilisés par les opérandes de sortie / d'entrée.

                  Plus d'opérandes, de contraintes et de clobber list


                  Il faut aussi préciser que pour un nombre <math>\(x\)</math> d'opérateurs (à la fois d'entrée et de sortie), alors le premier opérande de sortie est numéroté 0, et le dernier opérande d'entrée est numéroté <math>\(x-1\)</math>. Cela nous permet de manipuler directement nos variables dans le code assembleur, au contraire du code précédent où nous sommes passés par des registres bien spécifiques. Illustrons ce nouveau concept par un code :

                  int main(void)
                  {
                      int a = 10, b;
                      
                      __asm__
                      (
                          "movl %1, %%eax\n\t"
                          "movl %%eax, %0"
                              :"=r"(b)
                              :"r"(a)
                              :"%eax"
                      );
                      
                      printf("b = %d\n", b);
                      
                      return 0;
                  }
                  


                  Il y a deux opérandes, donc "=r"(b) est l'opérande 0, représentée par %0, et "r"(a) l'opérande 1, représentée par %1. Le code charge donc la variable a et stocker son contenu dans eax, qui est lui même copié dans la variable b. Ainsi à la fin de l'instruction, la variable a et la variable b valent toutes les deux 10. Cela nous permet de manipuler plus précisément les opérandes d'entrées et de sorties.

                  Cette possibilité s'étend également aux contraintes des opérandes. En effet, pour une opérande d'entrée, une contrainte composée d'un chiffre <math>\(x\)</math> qui signifie "cette entrée a les mêmes contraintes que la <math>\(x^{eme}\)</math> opérande de sortie". Cette technique est utilisée si on veut que l'opérande d'entrée et l'opérande de sortie soient stockées dans le même registre. Prenons un exemple :

                  int main(void)
                  {
                      int a = 10, b = 25;
                  
                      __asm__
                      (
                          "addl %2, %%eax"
                              : "=a"(a)
                              : "0"(a), "b"(b)
                      );
                  
                      printf("a += b = %d", a);
                  
                      return 0;
                  }
                  


                  Dans ce code, on demande à ce que l'opérande d'entrée <math>\(0\)</math> ait les mêmes contraintes que la <math>\(0^{eme}\)</math> opérande de sortie (soit "=a"). Ainsi, les deux variables seront stockées dans le registre eax. Sans cette technique, il aurait fallu préciser que l'opérande d'entrée <math>\(0\)</math> devait être stockée dans le registre eax.

                  Je finis en ajoutant des précisions sur la liste des registres pollués. Nous en avons parlé précédemment, mais nous n'avons pas tout dit dessus. Il y a en effet également d'autres précisions à ajouter.

                  • Si l'instruction modifie le registre de condition de code, alors il faut rajouter "cc" à cette liste.
                  • Si l'instruction modifie la mémoire de manière imprévisible, il faut ajouter "memory" à la liste. Si la mémoire modifiée n'est pas listée dans les opérandes d'entrée ou de sortie, il faut alors rajouter le mot-clef volatile.


                  Ce dernier point m'amène à la sous-partie suivante.

                  volatile



                  Ce mot-clef est bien connu des programmeurs système. Il permet de définir une variable de façon à ce que celle-ci ne puisse pas être placée dans un registre du processeur, mais en mémoire. Dans le cas de l'assembleur inline, il sert à empêcher les optimisations que pourrait faire GCC. En effet, le compilateur va essayer d'améliorer notre code pour l'optimiser et le rendre plus propre. Si jamais on veut qu'il respecte à la lettre le code que l'on a écrit, on utilisera ce mot-clef (à noter que l'on préfère souvent utiliser __volatile__ à la place de volatile).

                  Il est à noter que s'il n'est pas nécessaire (dans le cas de calculs, ou si le code ne produit aucun effet de bord), il ne sert à rien de le mettre. Dans ce cas il est mieux de laisser GCC optimiser le code.

                  Variables globales et fonctions


                  Depuis tout à l'heure, nous n'avons vu que le chargement de variables locales à une fonction. Il est pourtant possible de charger des variables globales, et c'est même encore plus facile ! En effet, il suffit d'écrire directement dans le code ceci : _ID, sans même passer par les opérandes d'entrées et de sortie. Exemple :

                  int b = 25;
                  
                  int main(void)
                  {
                      int a = 10;
                  
                      __asm__
                      (
                          "addl _b, %%eax"
                              : "=a"(a)
                              : "0"(a)
                      );
                  
                      printf("a += b = %d", a);
                  
                      return 0;
                  }
                  


                  Il est de même pour les appels de fonctions. Voici un exemple appelant la fonction puts :

                  const char * const str = "Hello world!";
                  
                  int main(void)
                  {
                      __asm__
                      (
                          "movl _str, %eax\n\t"
                          "pushl %eax\n\t"
                          "call _puts\n\t"
                          "add $8, %esp\n\t"
                          "leave\n\t"
                          "ret"
                      );
                  
                      return 0;
                  }
                  


                  Exemples



                  Pour illustrer cette grosse partie théorique, je vais prendre des exemples que j'ai pu voir sur Internet, accompagnés de quelques explications.

                  Mise à zéro de bit

                  __asm__
                  (   "btsl %1,%0"
                         : "=m" (ADDR)
                         : "Ir" (pos)
                         : "cc"
                  );
                  


                  Ce code permet de mettre à 1 le bit numéro <math>\(pos\)</math> de l'adresse ADDR. Si on avait voulu mettre le bit à 0, on aurait utilisé l'instruction btrl.

                  strcpy
                  Ce code tiré de la Glibc de Linux est celui de la fonction strcpy :

                  static inline char * strcpy(char * dest,const char *src)
                  {
                      int d0, d1, d2;
                  
                      __asm__ __volatile__
                      (  
                         "1:\tlodsb\n\t"
                         "stosb\n\t"
                         "testb %%al,%%al\n\t"
                         "jne 1b"
                             : "=&S" (d0), "=&D" (d1), "=&a" (d2)
                             : "0" (src),"1" (dest) 
                             : "memory"
                      );
                  
                      return dest;
                  }
                  


                  L'adresse de la chaîne source est située dans esi, celle de la chaîne de destination dans edi. Dès que l'on atteint 0, la copie est terminée. Les contraintes "&S", "&D", "&a" indiquent que les registres esi, edi and eax sont dans la liste des registres modifiés car leur valeur change durant l'exécution. L'instruction lodsb charge dans le registre al l'octet adressé par di:si, si le flag DF vaut 0 après ça, si est incrémenté, sinon décrémenté. L'instruction stosb stocke le contenu de al dans l'octet pointé par es:di, si le flag DF vaut 0 après ça, di est incrémenté, sinon décrémenté.

                  Des instructions inaccessibles ?
                  Il est fréquent lors de la création d'un système d'exploitation d'écrire sur divers ports (pour s'adresser au PIC par exemple), ou bien pour activer / désactiver les interruptions. Or il n'existe pas en C de fonction pour se faire. On a donc recours à l'assembleur inline. Dans cette exemple, on utilise des #define, ce qui s'avère pratique quand on appelle plusieurs fois la même instruction.

                  /* désactive les interruptions */
                  #define cli __asm__("cli"::)
                  
                  /* réactive les interruptions */
                  #define sti __asm__("sti"::)
                  
                  /* écrit un octet sur un port */
                  #define outb(port,value) \
                  	__asm__ __volatile__ ("outb %%al, %%dx" :: "d" (port), "a" (value));
                  
                  /* lit un octet sur un port */
                  #define inb(port)(    \
                  	unsigned char _v;       \
                  	__asm__ __volatile__ ("inb %%dx, %%al" : "=a" (_v) : "d" (port)); \
                          _v;     \
                  })
                  


                  Utiliser la syntaxe Intel


                  Pour ceux qui maitriserait mal la syntaxe AT&T ou qui par gouts personnels préfèrent la syntaxe Intel, il est possible d'utiliser cette dernière. Pour cela, il suffit de rajouter deux lignes dans son code assembleur : ".intel_syntax noprefix\n\t" au début et ".att_syntax" à la fin. Toute instruction écrite entre ces deux lignes sera considérée comme utilisant la syntaxe Intel. Exemple :

                  int a;
                  
                  __asm__
                  (
                      ".intel_syntax noprefix\n\t"
                      "mov ax, 2\n\t"
                      "shl ax, 2\n\t"
                      ".att_syntax"
                         :"=r"(a)
                  );
                  


                  Concernant le passage en argument, la méthode est quasiment la même que pour la syntaxe AT&T. Il suffit de rajouter des crochets autours de l'identificateur ou du numéro de la variable. Exemple avec une variable globale puis un paramètre de fonction (la méthode est identique pour les variables locales).

                  const char * const str = "Hello world!";
                  
                  void Aff(void)
                  {
                      __asm__
                      (
                          ".intel_syntax noprefix\n\t"
                      /* seulement des crochets en plus */
                          "mov eax, [_str]\n\t"
                          "push eax\n\t"
                          "call _puts\n\t"
                          "add esp, 8\n\t"
                          "leave\n\t"
                          "ret\n\t"
                          ".att_syntax"
                      );
                  }
                  


                  void Aff(const char * const str)
                  {
                      __asm__
                      (
                          ".intel_syntax noprefix\n\t"
                          "push eax\n\t"
                      /* seulement des crochets en plus */
                          "mov eax, [%0]\n\t"
                          "call _puts\n\t"
                          "add esp, 8\n\t"
                          "leave\n\t"
                          "ret\n\t"
                          ".att_syntax"
                              :
                              : "r"(str)
                      );
                  }
                  


                  Pour plus d'information, la documentation officielle est disponible ici.

                  Visual Studio



                  Visual Studio permet également d'insérer des routines en assembleur dans un code C (mais en utilisant la syntaxe Intel) grâce au mot-clef __asm (comme pour GCC, il est recommandé de ne pas utiliser le mot-clef asm). La syntaxe est la suivante :

                  __asm
                  {
                      mov al, 2
                      mov dx, 0xD007
                      out dx, al
                  }
                  


                  Il existe une variante de cette syntaxe, du fait que le mot-clef est un séparateur :

                  __asm mov al, 2
                  __asm mov dx, 0xD007
                  __asm out dx, al
                  


                  La première solution est la plus avantageuse car elle nécessite d'écrire moins de code et permet de bien séparer la routine assembleur du reste du code.

                  Interfacer avec le C



                  Un bloc __asm permet d'utiliser des éléments du langage C :

                  • les labels, les identificateurs de variables et de fonction ;
                  • les constantes symboliques et les énumérations ;
                  • les macros et directives de préprocesseur ;
                  • des structures, des unions et des typedef.


                  Quelques exemples pour illustrer :

                  /* Appel de membres de structures */
                  
                  struct first_type
                  {
                     char * weasel;
                     int same_name;
                  };
                  
                  struct second_type
                  {
                     int wonton;
                     long same_name;
                  };
                  
                  int main(void)
                  {
                     struct first_type hal;
                     struct second_type oat;
                  
                     __asm
                     {
                        /* Obligation d'utiliser 'hal' */
                        mov ecx, [ebx]hal.same_name
                        /* Utilisation de 'hal' facultative */
                        mov esi, [ebx].weasel    
                     }
                  
                  /* Le principe est le même pour la structure 'oat' */
                  }
                  


                  #include <stdio.h>
                  #define SIZE  5
                  
                  int main(void)
                  {
                  	int var;
                  
                  	puts("Donne une valeur : ");
                  	scanf("%d", &var);
                  
                  	__asm
                  	{
                  		mov eax, var
                  		shl eax, SIZE
                  		mov var, eax
                  	}
                  
                  	printf("\nvar << %d = %d\n", SIZE, var);
                  }
                  


                  Pour plus d'informations, la référence reste la documentation officielle et Internet.



                  • Partager sur Facebook
                  • Partager sur Twitter
                  Anonyme
                    19 juillet 2012 à 0:28:46

                    Pour les marcos ça serait bien d'en citer les plus usées,et pour le préprocesseur Pouet en parle dans son tuto,et y a aussi un passage dans celui de M@teo21.
                    • Partager sur Facebook
                    • Partager sur Twitter
                      19 juillet 2012 à 10:30:24

                      Je m'occuperai de restrict/auto ( :-° ) si j'ai le temps.
                      • Partager sur Facebook
                      • Partager sur Twitter
                      Staff désormais retraité.
                        19 juillet 2012 à 11:50:20

                        Salut,

                        L'idée est intéressante, cependant est-il nécessaire de faire un sujet à part de la FAQ C ? Il me semble que cela y aurait sa place, non ?

                        Sinon, juste pour dire, asm n'est pas un mot-clé du C, au même titre que fortran. Il est toutefois déconseillé de les utilisé car il s'agit d'extensions courantes (voy. Annexe J § 5). Néanmoins, je trouve cela intéressant d'en parler :)

                        Aussi, histoire de me faire un peu de pub, la liste des mots-clés est disponible dans le dernier chapitre de mon tutoriel sur les identificateurs (à jour par rapport au C11) ou tout simplement au § 6.4.1 al 1 p 58 de la norme C11 (n1570).

                        Citation : Lucas-84


                        Je m'occuperai de restrict/auto ( :-° ) si j'ai le temps.



                        Bonne chance pour restrict :-°
                        Sinon, je me demande si auto, static, register et _Thread_Local ne devraient pas être traiter ensemble afin de présenter les notions de durée de vie et de classe de stockage des objets.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          19 juillet 2012 à 12:20:31

                          Citation

                          Bonne chance pour restrict :-°



                          J'avais un vieux tuto en préparation à ce sujet, j'espère que le dépoussiérage ne sera pas trop violent. Mais bon, vu l'infâme passage de la norme sur les pointeurs restreints, ça donne plutôt envie de gerber.
                          • Partager sur Facebook
                          • Partager sur Twitter
                          Staff désormais retraité.
                            19 juillet 2012 à 12:26:14

                            Citation : Lucas-84


                            J'avais un vieux tuto en préparation à ce sujet, j'espère que le dépoussiérage ne sera pas trop violent.



                            Ah ! Je vois que je ne suis pas le seul à y avoir pensé :p
                            Sauf qu'en ce qui me concerne, je n'ai encore rien rédigé :-°

                            À noter que rz0 a écrit un article qui est pas mal du tout à ce sujet.

                            Citation : Lucas-84


                            Mais bon, vu l'infâme passage de la norme sur les pointeurs restreints, ça donne plutôt envie de gerber.


                            +10
                            • Partager sur Facebook
                            • Partager sur Twitter
                              19 juillet 2012 à 12:27:46

                              Citation : Taurre

                              Citation : Lucas-84


                              J'avais un vieux tuto en préparation à ce sujet, j'espère que le dépoussiérage ne sera pas trop violent.



                              Ah ! Je vois que je ne suis pas le seul à y avoir pensé :p
                              Sauf qu'en ce qui me concerne, je n'ai encore rien rédigé :-°

                              À noter que rz0 a écrit un article qui est pas mal du tout à ce sujet.



                              Oui, d'ailleurs je m'étais légèrement inspiré de celui-ci.
                              • Partager sur Facebook
                              • Partager sur Twitter
                              Staff désormais retraité.
                                19 juillet 2012 à 12:59:02

                                Si vous voulez répertorier des mots-clés du C, autant le faire aussi pour les extensions des compilos que les débutants seront susceptibles d'utiliser, MSVC, GCC voire Clang, et ça vous en ajoute un paquet...

                                Sinon pour restrict, j'ai quand même des doutes sur le fait d'essayer d'expliquer ça à des débutants...
                                • Partager sur Facebook
                                • Partager sur Twitter
                                  19 juillet 2012 à 13:33:46

                                  Mot-clef

                                  Toute :
                                  Type de donnée d'entier positif ou négatif codé généralement sur 16 ou 32 bits(celon l'OS et l'architecture), permet de réaliser des affectations de type et des cast :

                                  Renvoyer la taille d'un entier
                                  size_t tailleInt(void)
                                  {
                                    //Retourne le nombre d'octet utiliser pour un int
                                    return sizeof(int);
                                  
                                  }
                                  


                                  Affectation de type à une variable
                                  int maVariable;//maVariable est maintenant un entier positif ou négatif
                                  


                                  Cast d'une variable:
                                  size_t ma_variable = 5;
                                  int maVariable = (int)ma_variable;
                                  


                                  Dite moi si des chose sont à modifier
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    19 juillet 2012 à 13:43:41

                                    Ca marche pas pour tous les mots clés, ça ^^
                                    tu déclares pas une variable avec if ou sizeof :p

                                    ==> http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
                                    Lit la partie : 6.4.1 Keywords
                                    qui définie les mots clés : ils utilisent une liste, pas une phrase ^^
                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                    perror(const char * str); will save your life !
                                    Anonyme
                                      19 juillet 2012 à 13:50:38

                                      J'ai mis la partie sur asm en secret dans mon précédant post.

                                      Après concernant les extensions, faut voir. On peut déjà faire toutes celles listées dans la norme comme extensions courantes. Parce que sinon, si on fait toutes celles de GCC ou de VC++, on a effectivement pas fini.

                                      @Taurre : toi qui t'y connais bien en assembleur inline, t'as des remarques à formuler ? :)
                                      Sinon je ne peux pas accéder à ton tutoriel, il me dit que je n'ai pas le droit de le lire.
                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        19 juillet 2012 à 13:57:54

                                        @florent M : Apparemment, il y a eu un petit problème avec la mise en forme. Il faut mettre les informations après les deux-points (là c'est chaud à lire).

                                        Citation

                                        Sinon je ne peux pas accéder à ton tutoriel, il me dit que je n'ai pas le droit de le lire.



                                        Yep, il t'a filé un lien vers la version hors ligne. Ceci devrait marcher.
                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                        Staff désormais retraité.
                                        Anonyme
                                          19 juillet 2012 à 14:01:28

                                          Citation : Lucas-84

                                          Yep, il t'a filé un lien vers la version hors ligne. Ceci devrait marcher.



                                          Merci, ça marche mieux déjà. :)

                                          Sinon, concernant fortran, j'ai pas trouvé des masses d'infos. Quelqu'un s'y connait bien ?
                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            19 juillet 2012 à 15:04:15

                                            Je passe juste pour intervenir sur un point : il est possible (et même souhaitable) de regrouper les mots-clés qui vont ensemble. Au sujet de la FAQ : liste des mots-clés est quand même relativement conséquente, et seuls quelques-uns sont vraiment des FAQ. Je vois plus ce topic comme une démarche encyclopédique, un genre de doc du zéro...

                                            if, else

                                            Norme : C89/C99/C11
                                            Description :

                                            La construction if permet d'exécuter une instruction (ou un bloc d'instructions) sous réserve qu'une certaine condition soit remplie. Le mot-clé else permet d'introduire une instruction (ou un bloc) alternative, qui est exécutée si la condition n'est pas remplie.

                                            On commence par écrire le mot-clé if, suivi d'une condition entre parenthèses, elle-même suivie d'une instruction ou d'un bloc (voir exemples).

                                            La condition est une expression, qui sera considérée comme « vraie » seulement si sa valeur est non-nulle. Les opérateurs de comparaison <, <=, >, >= et == renvoient 1 si la relation (plus petit, plus grand...) est vérifiée, 0 sinon ; ils s'intègrent donc parfaitement dans les conditions, bien qu'ils puissent être utilisés ailleurs.

                                            On dispose également des opérateurs logiques &&, || et !, respectivement le « et », le « ou » et le « non » : le premier renvoie 1 si ses deux opérandes sont non-nuls, 0 sinon ; le second renvoie 1 si l'un de ses opérandes est non-nul, 0 sinon ; le troisième renvoie 1 si son opérande est nul, 0 sinon. Comme les opérateurs de comparaison, les opérateurs logiques sont parfaits pour les conditions, mais ils peuvent parfois être utilisés ailleurs.

                                            En outre, les opérateurs && et || ont un comportement de court-circuit. Par exemple, dans a && b, si a == 0, l'expression entière vaudra 0, quelque soit la valeur de b ; ce dernier n'est donc même pas évalué. De la même manière, dans a || b, si a est non-nul, b n'est même pas évalué : l'ensemble vaut 1. Ce système de court-circuit, combiné au fait que NULL == 0, permet d'écrire des conditions concises et élégantes (voir exemple 3).

                                            TODO :
                                            - avertissements sur = et strcpy ;
                                            - else ;
                                            - les blocs (et comment marche else if).

                                            Exemples :

                                            if(n < 0 || n > 42)
                                            {
                                                puts("Bonjour !");
                                            }
                                            else 
                                            {
                                                /* L'instruction à l'intérieur du else peut être un if à son tour */
                                                if(n > 32)
                                                {
                                                    puts("Salut !");
                                                }
                                                else
                                                {
                                                    puts("Bonsoir !");
                                                }
                                            }
                                            


                                            Dans cet exemple, chaque bloc ne contient qu'une seule instruction, on peut donc supprimer les accolades et réarranger le code comme ceci :

                                            if(n < 0 || n > 42)
                                                puts("Bonjour !");
                                            else if(n > 32)
                                                puts("Salut !");
                                            else
                                                puts("Bonsoir !");
                                            


                                            On peut exploiter le « court-circuitage » de l'opérateur && dans les conditions :

                                            struct Vect2D {
                                                int x, y;
                                            };
                                            
                                            /* Plus loin... */
                                            struct Vect2D *p = readVectFromFile(stdin);
                                            
                                            /* Si p == NULL, alors p->x < 0 n'est jamais évalué. */
                                            if(p != NULL && p->x < 0)
                                            {
                                                puts("The abscissa is negative !");
                                            }
                                            




                                            Bon, OK, c'était un poil trollant comme contribution. :p
                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                            J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.
                                            Anonyme
                                              19 juillet 2012 à 15:07:16

                                              J'aime bien ton post GuilOooo. Je propose de l'intégrer au topic (que tu dois créer). :p

                                              De toute façon, y'aura forcément des mots-clefs qui seront vite traités.
                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                19 juillet 2012 à 15:17:13

                                                @GuilOoo : Quitte à faire une partie sur if & else autant ne pas s'arrêter à ce que tout le monde sait, on pourrait expliquer en détail la façon dont le if évalue les condition (et ainsi expliquer la différence entre = et == et le fonctionnement de !, && et ||) avec même pourquoi pas une rapide explication des tables de vérités.

                                                Si non pensez à ajouter le type BOOL, ça peut pas faire de mal.

                                                Et pourquoi ne pas intégrer les type définie par windows.h genre DWORD, WIN32_FIND_DATA, HANDLE ... nan je rigole :p
                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                Si debugger, c’est supprimer des bugs, alors programmer ne peut être que les ajouter - Edsger Dijkstra
                                                  19 juillet 2012 à 15:19:50

                                                  Citation : damjuve

                                                  @GuilOoo : Quitte à faire une partie sur if & else autant ne pas s'arrêter à ce que tout le monde sait, on pourrait expliquer en détail la façon dont le if évalue les condition (et ainsi expliquer la différence entre = et == et le fonctionnement de !, && et ||) avec même pourquoi pas une rapide explication des tables de vérités.



                                                  Là, pour le coup, c'est redondant avec une partie de la FAQ. Mais pourquoi pas, je vais le rajouter.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  J'ai déménagé sur Zeste de savoir — Ex-manager des modérateurs.
                                                    19 juillet 2012 à 15:21:36

                                                    Citation : Lucas-84


                                                    Citation

                                                    Sinon je ne peux pas accéder à ton tutoriel, il me dit que je n'ai pas le droit de le lire.



                                                    Yep, il t'a filé un lien vers la version hors ligne. Ceci devrait marcher.



                                                    Oups, en effet, au temps pour moi :-°
                                                    Merci pour la correction ;)

                                                    Citation : informaticienzero


                                                    Après concernant les extensions, faut voir. On peut déjà faire toutes celles listées dans la norme comme extensions courantes. Parce que sinon, si on fait toutes celles de GCC ou de VC++, on a effectivement pas fini.



                                                    Cela me semble le plus logique histoire d'assurer un maximum de portabilité.

                                                    Citation : informaticienzero


                                                    @Taurre : toi qui t'y connais bien en assembleur inline, t'as des remarques à formuler ? :)



                                                    Hum... en fait, je ne m'y connais pas vraiment en Assembleur inline, j'ai juste fais deux ou trois test et lu en partie la documentation sur le site du projet GNU. Faut dire aussi que la syntaxe me rebute un peu... :-°

                                                    @GuilOooo : au sujet de l'intégration dans la FAQ C, je pensais avoir une entrée regroupant tous les mots-clés sous forme de liens menant chacun à une autre entrée décrivant ce dernier. Aussi, je ne pense personnellement pas que cela alourdiras trop la FAQ, maintenant ce n'est que mon avis.
                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                    Anonyme
                                                      19 juillet 2012 à 15:26:15

                                                      Citation : Taurre

                                                      Citation : informaticienzero


                                                      Après concernant les extensions, faut voir. On peut déjà faire toutes celles listées dans la norme comme extensions courantes. Parce que sinon, si on fait toutes celles de GCC ou de VC++, on a effectivement pas fini.



                                                      Cela me semble le plus logique histoire d'assurer un maximum de portabilité.



                                                      Je suis d'accord, déjà présenter celles de la norme, et si jamais y'a une extension utile d'un compilateur, à voir.

                                                      Citation : Taurre

                                                      Citation : informaticienzero


                                                      @Taurre : toi qui t'y connais bien en assembleur inline, t'as des remarques à formuler ? :)



                                                      Hum... en fait, je ne m'y connais pas vraiment en Assembleur inline, j'ai juste fais deux ou trois test et lu en partie la documentation sur le site du projet GNU. Faut dire aussi que la syntaxe me rebute un peu... :-°



                                                      Moi aussi je me suis servi de la documentation. Mais c'est vrai que l'assembleur inline de GCC n'est pas le plus pratique. Je préfère celui de Visual, notamment pour utiliser des variables dans le code assembleur.

                                                      Citation : Taurre

                                                      @GuilOooo : au sujet de l'intégration dans la FAQ C, je pensais avoir une entrée regroupant tous les mots-clés sous forme de liens menant chacun à une autre entrée décrivant ce dernier. Aussi, je ne pense personnellement pas que cela alourdiras trop la FAQ, maintenant ce n'est que mon avis.



                                                      Personnellement je ne sais pas trop. Faudrait pas non plus que la FAQ devienne le "fourre-tout" des trucs intéressants du C. Déjà que la section "Divers" se remplit de plus en plus.
                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        19 juillet 2012 à 15:31:22

                                                        Citation : informaticienzero


                                                        Personnellement je ne sais pas trop. Faudrait pas non plus que la FAQ devienne le "fourre-tout" des trucs intéressants du C. Déjà que la section "Divers" se remplit de plus en plus.



                                                        Bah ça reste une FAQ, donc par définition c'est fourre-tout. Si on part du principe que les zéros ont souvent des questions sur les mots clefs ça a sa place non ?
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Si debugger, c’est supprimer des bugs, alors programmer ne peut être que les ajouter - Edsger Dijkstra
                                                          19 juillet 2012 à 15:34:46

                                                          Citation : informaticienzero


                                                          Citation : Taurre

                                                          Citation : informaticienzero


                                                          @Taurre : toi qui t'y connais bien en assembleur inline, t'as des remarques à formuler ? :)



                                                          Hum... en fait, je ne m'y connais pas vraiment en Assembleur inline, j'ai juste fais deux ou trois test et lu en partie la documentation sur le site du projet GNU. Faut dire aussi que la syntaxe me rebute un peu... :-°



                                                          Moi aussi je me suis servi de la documentation. Mais c'est vrai que l'assembleur inline de GCC n'est pas le plus pratique. Je préfère celui de Visual, notamment pour utiliser des variables dans le code assembleur.



                                                          Note que l'ASM inline de MSVC permet de faire beaucoup moins de choses (spécifier finement où tu veux tes variables, quels registres sont touchés, etc.)...
                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                          Anonyme
                                                            19 juillet 2012 à 15:38:35

                                                            Citation : damjuve

                                                            Citation : informaticienzero


                                                            Personnellement je ne sais pas trop. Faudrait pas non plus que la FAQ devienne le "fourre-tout" des trucs intéressants du C. Déjà que la section "Divers" se remplit de plus en plus.



                                                            Bah ça reste une FAQ, donc par définition c'est fourre-tout. Si on part du principe que les zéros ont souvent des questions sur les mots clefs ça a sa place non ?



                                                            Je ne sais pas. Je laisse à GuilOooo le soin de décider.

                                                            Citation : rz0

                                                            Citation : informaticienzero


                                                            Citation : Taurre

                                                            Citation : informaticienzero


                                                            @Taurre : toi qui t'y connais bien en assembleur inline, t'as des remarques à formuler ? :)



                                                            Hum... en fait, je ne m'y connais pas vraiment en Assembleur inline, j'ai juste fais deux ou trois test et lu en partie la documentation sur le site du projet GNU. Faut dire aussi que la syntaxe me rebute un peu... :-°



                                                            Moi aussi je me suis servi de la documentation. Mais c'est vrai que l'assembleur inline de GCC n'est pas le plus pratique. Je préfère celui de Visual, notamment pour utiliser des variables dans le code assembleur.



                                                            Note que l'ASM inline de MSVC permet de faire beaucoup moins de choses (spécifier finement où tu veux tes variables, quels registres sont touchés, etc.)...



                                                            C'est vrai, pour une utilisation poussée je me tournerais vers GCC, mais si c'est une petite routine simple, je préfèrerais faire quelque chose comme avec VC++. De toutes façons, on a pas trop le choix puisque l'assembleur dépend du compilateur choisi.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                              19 juillet 2012 à 15:41:30

                                                              Citation : informaticienzero


                                                              C'est vrai, pour une utilisation poussée je me tournerais vers GCC, mais si c'est une petite routine simple, je préfèrerais faire quelque chose comme avec VC++. De toutes façons, on a pas trop le choix puisque l'assembleur dépend du compilateur choisi.



                                                              Vu les capacités limitées de MSVC regardant l'ASM inline, autant coder tes routines en ASM à part, et assembler à part (avec l'assembleur de ton choix). Et là c'est pas spécifique à un compilateur donné, d'ailleurs.
                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Les mots clefs du C

                                                              × 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