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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre chevronné Avatar de der§en
    Homme Profil pro
    Bretagne
    Inscrit en
    Septembre 2005
    Messages
    1 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bretagne
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 070
    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 : 145
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
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 089
    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 chevronné Avatar de der§en
    Homme Profil pro
    Bretagne
    Inscrit en
    Septembre 2005
    Messages
    1 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bretagne
    Secteur : Industrie

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

    A suivre....

  4. #4
    Expert éminent
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 14 089
    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
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

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

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    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 chevronné Avatar de der§en
    Homme Profil pro
    Bretagne
    Inscrit en
    Septembre 2005
    Messages
    1 070
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bretagne
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 070
    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 ?

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