Difference between revisions of "Flexible Array Member/fr"

From Lazarus wiki
Jump to navigationJump to search
(Created page with "{{Flexible_Array_Member}} 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 compila...")
 
Line 4: Line 4:
  
 
==Introduction==
 
==Introduction==
'''Disclaimer:''' ''this section is pretty much a copy-paste from [https://en.wikipedia.org/wiki/Flexible_array_member Wikipedia article]''
+
'''Avertissement:''' ''cette section est à peu près un copier-coller de l'[https://en.wikipedia.org/wiki/Flexible_array_member article Wikipedia]''
  
Flexible Array Member is a member of a struct, which is an array without a given dimension. It must be the last member of such a struct and it must be accompanied by at least one other member, as in the following example:
+
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:
 
<source lang="c">
 
<source lang="c">
 
typedef struct mystruct
 
typedef struct mystruct
Line 12: Line 12:
 
   DWORD a;
 
   DWORD a;
 
   DWORD b;
 
   DWORD b;
   DWORD c[]; // the flexible array member must be last
+
   DWORD c[]; // le membre tableau flexible doit être le dernier
 
};
 
};
 
</source>
 
</source>
Typically, such structures serve as the header in a larger, variable memory allocation:
+
Généralement,de tels struct servent d'entête dans une plus large allocation mémoire variable:
  
 
<source lang="c">
 
<source lang="c">
Line 24: Line 24:
 
</source>
 
</source>
  
The sizeof operator on such a struct gives the size of the structure as if the flexible array member was empty. This may include padding added to accommodate the flexible member; the compiler is also free to re-use such padding as part of the array itself.
+
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.
  
It is common to allocate sizeof(struct) + array_len*sizeof(array element) bytes
+
Il est courant d'allouer sizeof(struct) + array_len*sizeof(array element) octets.
  
 
==Pascal==
 
==Pascal==

Revision as of 13:42, 30 April 2022

English (en) français (fr)

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.

Introduction

Avertissement: cette section est à peu près un copier-coller de l'article Wikipedia

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:

typedef struct mystruct
{
  DWORD a;
  DWORD b;
  DWORD c[]; // le membre tableau flexible doit être le dernier
};

Généralement,de tels struct servent d'entête dans une plus large allocation mémoire variable:

struct mystruct* st= malloc(...);
...
for (int i = 0; i < st->b; i++)
     st->c[i] = ...;

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.

Il est courant d'allouer sizeof(struct) + array_len*sizeof(array element) octets.

Pascal

Pascal doesn't have flexible array member, thus the structure should be declared without the additional member, in order for sizeof(mystruct) to return the same value as in C.

type
  mystruct = record
    a : DWORD;
    b : DWORD;
  end;
  pmystruct = ^mystruct;

There are a few options on how the additional elements can be accessed:

Adressage direct

By explicitly getting the address that goes after the header strucut

var
 i   : integer;
 buf : Pmystruct;
 c   : PDword;
begin
  GetMem(buf, sizeof(mystruct)+ extrasize);
  ...
  c:=Pointer(buf)+sizeof(mystruct);
  
  for i := 0 to buf.b-1 do
     c[i] := ...;

Using Additional Record

Depending on the use, the additional record could overlap with the original record using absolute.

type
  mystructEx = record
    hdr : mystruct;
    c : PDword;
  end;
  pmystructEx = ^mystructEx;


var
 i   : integer;
 buf : PmystructEx;
begin
  GetMem(buf, sizeof(mystruct)+ extrasize);
  
  for i := 0 to buf.hdr.b-1 do
     buf.c[i] := ...;

Utilisation d'enegistrement avancé

Advanced records allow to methods and properties for records. Thus the field could be emulated through a method/property

{$modeswitch advancedrecords}

type
  mystruct = packed record
    a,b: DWORD;
    function c: PDWORD; inline;
  end;
 
function mystruct.c: PDWORD;
begin
  Result := PDWORD(pbyte(@self.b)+sizeOf(self.b));
end;

OR using an empty record. (An empty record has not struct, yet allows to get an address, which should save some time on address calculation)

{$modeswitch advancedrecords}

type
  mystruct = packed record
    a,b: DWORD;
    function c: PDWORD; inline;
  strict private
    cStart: record end;
  end;
 
function mystruct.c: PDWORD;
begin
  Result := PDWORD(@cStart);
end;

Voir aussi