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

Delphi Discussion :

Est-ce moi ou sizeof qui bug ?


Sujet :

Delphi

  1. #1
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 765
    Points : 960
    Points
    960
    Par défaut Est-ce moi ou sizeof qui bug ?
    Voila, un record, qui normalement ne devrait faire que 16 bits soit un Word, et donc un sizeof = 2.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    type
      TLocalisation = packed record
        Altitude: 0..4095;
        Biome:    0..15;
      end;
    Sauf que lors du contrôle de l'espace occupé, j'ai ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var
      taille: word;
    begin
      taille := Sizeof(TLocalisation);
     
      ShowMessage('Taille = ' + taille.ToString);
    Nom : Sizeof.png
Affichages : 129
Taille : 1,7 Ko

    Une idée de mon erreur (bien qu'il me semble que cela donnais bien 2 dans mon ancien Delphi 10.2) ?

  2. #2
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Delphi ne gère pas de champ de moins d'un byte

    4095 c'est 12 bit aligné sur 16 bit
    15 c'est 4 bit aligné sur 8 bit;

    la packed lui évite un alignement sur 4 voire 8 octet, par exemple un champ 16 bit en plus après Biome, packed, il suit directement, en normal, il aurait été aligné à 4 et tu aurais un petit trou d'un octet.

    Donc 24 bits confirmé

    ce n'est pas comme en C ou tu peux écrire

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct  TLocalisation {
        unsigned short Altitude: 12;
        unsigned short Biome: 4
    }
    Et encore, il aligne aussi le bit field, la ça tombe pile dans la taille d'un short
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct  TLocalisation {
        unsigned short Altitude: 12;
        unsigned char Biome: 4
    }
    Dans ce cas, est-ce qu'il cumule short 12 + char 4, où comme le type est différent, il ajoute un trou de 4 bit, donc aligné aussi sur 16 pour Altitude

    Qui provoque des instructions complexes pour la manipulation, en dehors d'un header de fichier ou de flux, mieux vaut éviter de nos jours, on a assez de RAM pour supporter un peu d'alignement et éviter du OR, AND, SHR, on sacrifie un peu de mémoire au profit du CPU
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  3. #3
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 765
    Points : 960
    Points
    960
    Par défaut
    Je vais refaire le même test sur une ancienne version !

    A suivre....

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Citation Envoyé par der§en Voir le message
    Je vais refaire le même test sur une ancienne version !

    A suivre....
    Tu peux, j'en suis certains puisque l'API Windows en contient

    Code c : 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
    22
    23
    24
    typedef struct _LDT_ENTRY {
      WORD  LimitLow;
      WORD  BaseLow;
      union {
        struct {
          BYTE BaseMid;
          BYTE Flags1;
          BYTE Flags2;
          BYTE BaseHi;
        } Bytes;
        struct {
          DWORD BaseMid : 8;
          DWORD Type : 5;
          DWORD Dpl : 2;
          DWORD Pres : 1;
          DWORD LimitHi : 4;
          DWORD Sys : 1;
          DWORD Reserved_0 : 1;
          DWORD Default_Big : 1;
          DWORD Granularity : 1;
          DWORD BaseHi : 8;
        } Bits;
      } HighWord;
    } LDT_ENTRY, *PLDT_ENTRY;

    en delphi, tu dois utiliser des mask et SHR/AND ou SHL/OR

    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    const
      { bitfield constants for Flags field of TLDTEntry }
     
      LDTF_BASEMID      = DWORD($FF000000);  {8}
      LDTF_TYPE_8       = $00F80000;  {5}
      LDTF_DPL          = $00060000;  {2}
      LDTF_PRES         = $00010000;  {1}
      LDTF_LIMITHI      = $0000F000;  {4}
      LDTF_SYS          = $00000800;  {1}
      LDTF_RESERVED_0   = $00000400;  {1}
      LDTF_DEFAULT_BIG  = $00000200;  {1}
      LDTF_GRANULARITY  = $00000100;  {1}
      LDTF_BASEHI       = $000000FF;  {8}
     
     
    type
      PLDTEntry = ^TLDTEntry;
      _LDT_ENTRY = record
        LimitLow: Word;
        BaseLow: Word;
        case Integer of
          0: (
            BaseMid: Byte;
            Flags1: Byte;
            Flags2: Byte;
            BaseHi: Byte);
          1: (
            Flags: Longint);
      end;
      {$EXTERNALSYM _LDT_ENTRY}
      TLDTEntry = _LDT_ENTRY;
      LDT_ENTRY = _LDT_ENTRY;
      {$EXTERNALSYM LDT_ENTRY}
    Ah oui c'est un cas connu depuis 2007 au moins
    et ici une belle démonstration pour encapsuler tout ça proprement
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 445
    Points
    28 445
    Par défaut
    sur un Delphi moderne tu peux t'en sortir comme ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    type
      TLocalisation = packed record
      private
        bits: Word;
        function GetAltitude: Word;
        procedure SetAltitude(Value: Word);
        function GetBiome: Byte;
        procedure SetBiome(Value: Byte);
      public
        property Altitude:Word read GetAltitude write SetAltiture;
        property Biome: Byte read GetBiome write SetBiome; 
      end;
    reste plus qu'à mettre à jour "bits"

    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
     
    function TLocalisation.getAltitude: Word;
    begin
      Result := bits and $FFF;
    end;
     
    procedure TLocation.SetAltitude(Value: Word);
    begin
      bits := Value or (bits and  $F000);
    end;
     
    function TLocalisation.getBiome: Byte;
    begin
      Result := bits shr 12;
    end;
     
    procedure TLocation.SetAltitude(Value: Byte);
    begin
      bits := (Word(Value) shl 12) or (bits and  $FFF);
    end;
    Developpez.com: Mes articles, forum FlashPascal
    Entreprise: Execute SARL
    Le Store Excute Store

  6. #6
    Membre éprouvé Avatar de der§en
    Homme Profil pro
    Chambord
    Inscrit en
    Septembre 2005
    Messages
    765
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loir et Cher (Centre)

    Informations professionnelles :
    Activité : Chambord
    Secteur : Transports

    Informations forums :
    Inscription : Septembre 2005
    Messages : 765
    Points : 960
    Points
    960
    Par défaut
    Merci de votre aide, de mon coté, j'ai aussi créuser du même coté que Paul.

    J'en était arrivé a ceci, que je vais comparer avec la solution de Paul:
    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
     
      TLocalisation = record
      private
        FContenu: Word;
        function  GetBiome: Word;
        procedure SetBiome(const AValue: Word);
        function  GetAltitude: Word;
        procedure SetAltitude(const AValue: Word);
      public
        property Biome: Word read GetBiome write SetBiome;
        property Altitude: Word read GetAltitude write SetAltitude;
      end;
     
    function TLocalisation.GetBiome: Word;
    begin
      Result := FContenu and $000F;
    end;
     
    procedure TLocalisation.SetBiome(const AValue: Word);
    begin
      FContenu := AValue + (FContenu and $FFF0);
    end;
     
    function TLocalisation.GetAltitude: Word;
    begin
      Result := (FContenu shr 4) and $0FFF;
    end;
     
    procedure TLocalisation.SetAltitude(const AValue: Word);
    begin
      FContenu := (AValue shl 4) + (FContenu and $000F);
    end;
    A votre avis, j'ai commis des erreurs de calculs ?

  7. #7
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 459
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 459
    Points : 24 873
    Points
    24 873
    Par défaut
    Tu est parti sur un BigEndian au lieu de LittleEndian, ça fonctionnera mais inverser en mémoire
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

Discussions similaires

  1. Réponses: 2
    Dernier message: 17/11/2015, 19h53
  2. Réponses: 4
    Dernier message: 04/03/2011, 11h19
  3. Est-ce moi ou il ya un gros bug dans la classe Calendar ?
    Par lafouine46 dans le forum Collection et Stream
    Réponses: 2
    Dernier message: 13/05/2007, 21h31
  4. [RCP]tuto Ibm qui bug
    Par sglug dans le forum Eclipse Platform
    Réponses: 2
    Dernier message: 03/10/2005, 15h11

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