Flexible Array Member/fr: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: Flexible Array Member/fr
| Old | New | Line | |
|---|---|---|---|
| 1 | + | C'est une caractéristique rarement utilisée en langage C. Elle a été introduite avec la norme C99. Elle n'a jamais été adoptée par le compilateur C++ (et cela pourrait être la raison de la rare utilisation). Quelques API à la C pourrait bénéficier de cette caractéristique, en particulier celles de bas niveau. | |
| 2 | + | ||
| 3 | + | ## Introduction | |
| 4 | + | ||
| 5 | + | **Avertissement:** *cette section est à peu près un copier-coller de l'[article Wikipedia](https://en.wikipedia.org/wiki/Flexible_array_member)* | |
| 6 | + | ||
| 7 | + | Le membre tableau flexible est un membre de struct, qui est un tableau sans dimension spécifiée. Il doit être le dernier membre d'un tel struct et doit être acompagné d'au moins un autre membre, comme dans l'exemple suivant: | |
| 8 | + | ||
| 9 | + | ``` c | |
| 10 | + | typedef struct mystruct | |
| 11 | + | { | |
| 12 | + | DWORD a; | |
| 13 | + | DWORD b; | |
| 14 | + | DWORD c[]; // le membre tableau flexible doit être le dernier | |
| 15 | + | }; | |
| 16 | + | ``` | |
| 17 | + | ||
| 18 | + | Généralement,de tels struct servent d'entête dans une plus large allocation mémoire variable: | |
| 19 | + | ||
| 20 | + | ``` c | |
| 21 | + | struct mystruct* st= malloc(...); | |
| 22 | + | ... | |
| 23 | + | for (int i = 0; i < st->b; i++) | |
| 24 | + | st->c[i] = ...; | |
| 25 | + | ``` | |
| 26 | + | ||
| 27 | + | L'operateur sizeof sur un tel struct donne la taille du struct comme si le membre tableau flexible était vide. Cela peut inclure un rembourrage ajouté pour accueillir l'élément flexible ; le compilateur est également libre de réutiliser ce remplissage dans le cadre du tableau lui-même. | |
| 28 | + | ||
| 29 | + | Il est courant d'allouer sizeof(struct) + array_len*sizeof(array element) octets. | |
| 30 | + | ||
| 31 | + | ## Pascal | |
| 32 | + | ||
| 33 | + | Pascal n'a pas de membre de tableau flexible, donc la structure doit être déclarée sans le membre supplémentaire, afin que sizeof(mystruct) renvoie la même valeur qu'en C. | |
| 34 | + | ||
| 35 | + | ``` pascal | |
| 36 | + | type | |
| 37 | + | mystruct = record | |
| 38 | + | a : DWORD; | |
| 39 | + | b : DWORD; | |
| 40 | + | end; | |
| 41 | + | pmystruct = ^mystruct; | |
| 42 | + | ``` | |
| 43 | + | ||
| 44 | + | Il existe quelques options pour accéder aux éléments supplémentaires : | |
| 45 | + | ||
| 46 | + | ### Adressage direct | |
| 47 | + | ||
| 48 | + | En obtenant explicitement l'adresse qui suit la structure d'en-tête | |
| 49 | + | ||
| 50 | + | ``` pascal | |
| 51 | + | var | |
| 52 | + | i : integer; | |
| 53 | + | buf : Pmystruct; | |
| 54 | + | c : PDword; | |
| 55 | + | begin | |
| 56 | + | GetMem(buf, sizeof(mystruct)+ extrasize); | |
| 57 | + | ... | |
| 58 | + | c:=Pointer(buf)+sizeof(mystruct); | |
| 59 | + | ||
| 60 | + | for i := 0 to buf.b-1 do | |
| 61 | + | c[i] := ...; | |
| 62 | + | ``` | |
| 63 | + | ||
| 64 | + | ### Utilisation d'enregistrement supplémentaire | |
| 65 | + | ||
| 66 | + | Selon l'utilisation, l'enregistrement supplémentaire pourrait chevaucher l'enregistrement d'origine en utilisant [[absolute/fr|absolute]]. | |
| 67 | + | ||
| 68 | + | ``` pascal | |
| 69 | + | type | |
| 70 | + | mystructEx = record | |
| 71 | + | hdr : mystruct; | |
| 72 | + | c : PDword; | |
| 73 | + | end; | |
| 74 | + | pmystructEx = ^mystructEx; | |
| 75 | + | ||
| 76 | + | var | |
| 77 | + | i : integer; | |
| 78 | + | buf : PmystructEx; | |
| 79 | + | begin | |
| 80 | + | GetMem(buf, sizeof(mystruct)+ extrasize); | |
| 81 | + | ||
| 82 | + | for i := 0 to buf.hdr.b-1 do | |
| 83 | + | buf.c[i] := ...; | |
| 84 | + | ``` | |
| 85 | + | ||
| 86 | + | ### Utilisation d'enegistrement avancé | |
| 87 | + | ||
| 88 | + | Les enregistrements avancés permettent d'utiliser des méthodes et des propriétés pour les enregistrements. Ainsi, le champ pourrait être émulé via une méthode/propriété | |
| 89 | + | ||
| 90 | + | ``` pascal | |
| 91 | + | {$modeswitch advancedrecords} | |
| 92 | + | ||
| 93 | + | type | |
| 94 | + | mystruct = packed record | |
| 95 | + | a,b: DWORD; | |
| 96 | + | function c: PDWORD; inline; | |
| 97 | + | end; | |
| 98 | + | ||
| 99 | + | function mystruct.c: PDWORD; | |
| 100 | + | begin | |
| 101 | + | Result := PDWORD(pbyte(@self.b)+sizeOf(self.b)); | |
| 102 | + | end; | |
| 103 | + | ``` | |
| 104 | + | ||
| 105 | + | OU en utilisant un enregistrement vide. (Un enregistrement vide n'a pas de structure, mais permet d'obtenir une adresse, ce qui devrait faire gagner du temps sur le calcul de l'adresse) | |
| 106 | + | ||
| 107 | + | ``` pascal | |
| 108 | + | {$modeswitch advancedrecords} | |
| 109 | + | ||
| 110 | + | type | |
| 111 | + | mystruct = packed record | |
| 112 | + | a,b: DWORD; | |
| 113 | + | function c: PDWORD; inline; | |
| 114 | + | strict private | |
| 115 | + | cStart: record end; | |
| 116 | + | end; | |
| 117 | + | ||
| 118 | + | function mystruct.c: PDWORD; | |
| 119 | + | begin | |
| 120 | + | Result := PDWORD(@cStart); | |
| 121 | + | end; | |
| 122 | + | ``` | |
| 123 | + | ||
| 124 | + | ## Voir aussi | |
| 125 | + | ||
| 126 | + | - <https://forum.lazarus.freepascal.org/index.php/topic,45998.0.html> - fil de discussion original qui a commencé la discussion | |
| 127 | + | - <https://en.wikipedia.org/wiki/Flexible_array_member> - article wikipedia sur les membres tableau flexible. | |
| 128 | + | - [[Common problems when converting C header files/fr|Problèmes courants lors de la conversion des fichiers d'entête C]] | |
| 129 | + | ||
| 130 | + | --- | |
| 131 | + | *From the Free Pascal wiki, page "Flexible Array Member/fr", as it stood on 2022-04-30 after a change by E-ric, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
