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

Lazarus Pascal Discussion :

Où et comment sont définis les $DEFINE système, machine, etc. ? [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 132
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut Où et comment sont définis les $DEFINE système, machine, etc. ?
    Bonjour,

    question bizarre, n'est-ce pas ? Mais il m'arrive toujours des trucs, à moi, que même pas vous imaginez !

    La preuve : comme je suis en train de continuer à étudier ces histoires de Scanline et que le PixelFormat des bitmaps a son importance là-dedans, j'ai eu l'idée d'utiliser la compilation conditionnelle à grands coups de $DEFINE.

    Et c'est comme ça que j'ai découvert que 24BIT était un DEFINE connu du système, en tout cas c'est ce qu'en laisse apparaître la coloration syntaxique :

    Nom : define.jpg
Affichages : 182
Taille : 26,1 Ko

    Et il suffit de rajouter une lettre devant 24 pour retrouver un fonctionnement classique.

    Pour en avoir le cœur net, je suis parti d'un nouveau projet vierge de chez vierge, et je confirme ce comportement bizarre.
    Vous pourriez tester chez vous ? Moi j'ai testé sous Linux et sous XP avec des Lazarus 32 bits.

    Pour tester c'est très simple, il suffit de copier/coller ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      {$IFDEF 24BIT}
        const
          bidon = 'toto';
      {$ENDIF}
    et de jouer à rajouter/enlever une lettre devant 24 tout en observant le changement de couleur.
    C'est ainsi que j'ai pu constater que BIT était connu, mais pas BT (ou alors je n'ai pas attendu assez longtemps ? J'ai remarqué également que le changement de couleur n'était parfois pas instantané...)

    En attendant, j'ai grave failli me faire avoir dans mon programme de test, mine de rien...

  2. #2
    Membre chevronné

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Par défaut
    A priori c'est un bug au niveau de l'IDE: si l'identifiant après le test "ifdef" commence par un chiffre, le test est alors toujours considéré comme positif.

    Exemple (affichage comme positif):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    {$IFDEF 2cecinexistepas}
      const
        bidon = 'toto';
    {$ENDIF}

  3. #3
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 132
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Merci pour ton retour et ton test
    Citation Envoyé par FChrisF Voir le message
    A priori c'est un bug au niveau de l'IDE: si l'identifiant après le test "ifdef" commence par un chiffre, le test est alors toujours considéré comme positif.


    Méfiance dans les codes, alors, car un truc genre {$IFDEF 24BIT} sera toujours vrai, même si 327 lignes plus haut vous avez mis {.$DEFINE 24BIT}; avec le point pour ne pas le définir !

    Bonjour le piège...

    Merci en tout cas de m'avoir confirmé que je ne marchais pas sur la tête, ça rassure

  4. #4
    Rédacteur

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    Février 2013
    Messages
    1 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 1 436
    Billets dans le blog
    84
    Par défaut
    Bonsoir,

    Citation Envoyé par FChrisF Voir le message
    A priori c'est un bug au niveau de l'IDE
    Petite précision : les directives sont gérées par le compilateur et non par l'EDI : c'est Free Pascal qui fait le travail dans ce cas.

    Citation Envoyé par FChrisF Voir le message
    si l'identifiant après le test "ifdef" commence par un chiffre, le test est alors toujours considéré comme positif.
    En fait, le compilateur attend un symbole qui obéit aux règles des identificateurs Pascal : il doit commencer par une lettre ou _. Ce qui suit le symbole est considéré comme un véritable commentaire (à éviter en général afin d'éviter les confusions).

    On peut regretter qu'il n'y ait pas au moins un avertissement dans le cas de la directive $DEFINE (comme pour $UNDEF d'ailleurs qui accepte des nombres sans broncher ).
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  5. #5
    Membre chevronné

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Par défaut
    Je me suis peut-être mal exprimé...

    Comme tout un chacun, je sais bien que les DEFINE sont des directives de compilation pour le compilateur.

    Mais nous parlons ici de l'affichage du code dans des blocs de test IFDEF/IFUNDEF au sein de l'IDE Lazarus. Celui-ci affiche en effet en exergue le code qui est sensé être compilé d'après les DEFINE présents au sein du projet.

    Et clairement, il y a un problème dans certain cas. Par exemple, d'après l'affichage au sein de Lazarus, les deux blocs de code suivants sont sensés être compilés (ce qui est bien sûr impossible):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {$ifdef 47ceciestimpossible}
      WriteLn('Impossible Defined.');
    {$endif}
    {$ifndef 47ceciestimpossible}
      WriteLn('Impossible NOT Defined.');
    {$endif}

    Par ailleurs, en ce qui concerne les conventions pour le nommage des 'symbol name', c'est loin d'être aussi clair (cf. documentation http://www.freepascal.org/docs-html/prog/progsu11.html, qui ne précise rien à ce sujet).

    Bien entendu, certaines "choses" sont impossibles (par exemple '*$', 'çé'), mais les conventions de nommage ne sont pas exactement celles des variables. Il est ainsi tout à fait possible de définir et d'utiliser des 'symbol names' commençant par un chiffre (voire même formés uniquement de chiffres).

    Exemple de symbol name autorisé:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    program project1;
     
    {$define 2ceciestuntest}
     
    begin
    {$ifdef 2ceciestuntest}
      WriteLn('Defined.');
    {$else}
      WriteLn('NOT Defined.');
    {$endif}
    end.

  6. #6
    Rédacteur

    Avatar de gvasseur58
    Homme Profil pro
    Cultivateur de code (bio)
    Inscrit en
    Février 2013
    Messages
    1 436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Cultivateur de code (bio)
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2013
    Messages : 1 436
    Billets dans le blog
    84
    Par défaut
    Citation Envoyé par FChrisF Voir le message
    Je me suis peut-être mal exprimé...
    Ce doit être mon cas aussi .


    Citation Envoyé par FChrisF Voir le message
    Mais nous parlons ici de l'affichage du code dans des blocs de test IFDEF/IFUNDEF au sein de l'IDE Lazarus. Celui-ci affiche en effet en exergue le code qui est sensé être compilé d'après les DEFINE présents au sein du projet.
    L'affichage ne fait que refléter le traitement effectif du compilateur : c'est ce dernier qui ne signale pas l'erreur. Pour le moment, je n'ai jamais pris en défaut l'affichage de l'EDI.

    Citation Envoyé par FChrisF Voir le message
    Et clairement, il y a un problème dans certain cas. Par exemple, d'après l'affichage au sein de Lazarus, les deux blocs de code suivants sont sensés être compilés (ce qui est bien sûr impossible):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    {$ifdef 47ceciestimpossible}
      WriteLn('Impossible Defined.');
    {$endif}
    {$ifndef 47ceciestimpossible}
      WriteLn('Impossible NOT Defined.');
    {$endif}
    C'est pourtant ce cas "impossible" que le compilateur traite sans souci . Cette portion de code se compile sans problème et écrit bien les DEUX messages.

    Citation Envoyé par FChrisF Voir le message
    Par ailleurs, en ce qui concerne les conventions pour le nommage des 'symbol name', c'est loin d'être aussi clair (cf. documentation http://www.freepascal.org/docs-html/prog/progsu11.html, qui ne précise rien à ce sujet).
    Il faut en fait se référer au début de la documentation qui est explicite :

    All programmer defined names in the source code –excluding reserved words– are designated as identifiers.
    Voir ici. Et l'on apprend que les identificateurs ne peuvent pas commencer par un chiffre...

    Citation Envoyé par FChrisF Voir le message
    Bien entendu, certaines "choses" sont impossibles (par exemple '*$', 'çé'), mais les conventions de nommage ne sont pas exactement celles des variables. Il est ainsi tout à fait possible de définir et d'utiliser des 'symbol names' commençant par un chiffre (voire même formés uniquement de chiffres).
    Là, je pense que c'est faux. Il est possible de les définir, mais pas de les utiliser sans produire des aberrations: c'est bien là qu'est le problème . L'exemple que tu donnes le montre d'ailleurs :

    Citation Envoyé par FChrisF Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    program project1;
    {$define 2ceciestuntest} // inutile : ce sera TOUJOURS VRAI comme tu l'as montré
     
    begin
    {$ifdef 2ceciestuntest} 
      WriteLn('Defined.');
    {$else}
      WriteLn('NOT Defined.');
    {$endif}
    end.
    Pour s'en convaincre, il suffit de remplacer $IFDEF par $IFNDEF pour se rendre compte que rien ne change : la première ligne est toujours activée, que le symbole ait été défini ou non . Le $ELSE fonctionne quant à lui correctement : il n'active pas la ligne qui suit puisque la première branche de l'alternative est vraie.

    Conclusion : $IFDEF et $IFNDEF souffrent du même problème qui est de ne pas lancer un avertissement sur l'appellation erronée du symbole.
    Et moralité : il ne faut utiliser que des identificateurs corrects au sens Pascal du terme.

    Mais je ne demande qu'à être contredit. Je serai d'accord avec Jipété pour dire que ce comportement est pour le moins déconcertant .
    Accès à mon site et à mon blog. Actualités, cours et ressources Delphi, Lazarus et Pascal.
    Pensez à la balise - Quelqu'un vous a aidé ou vous appréciez une intervention ? Pensez au

  7. #7
    Membre chevronné

    Homme Profil pro
    Autre
    Inscrit en
    Novembre 2015
    Messages
    145
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Autre

    Informations forums :
    Inscription : Novembre 2015
    Messages : 145
    Par défaut
    Ce que vous décrivez correspond en effet à l'affichage au sein de l'IDE, mais pas à la compilation réellement effectuée par le compilateur: en tous les cas, pas chez moi.

    Voici mon résultat pour les lignes de code suivantes:

    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
    program Project1;
     
    {$define 2ceciestuntest}
    //{$define 47ceciestimpossible}
     
    begin
     
    {$ifdef 2ceciestuntest}
      WriteLn('Defined.');
    {$else}
      WriteLn('NOT Defined.');
    {$endif}
     
    {$ifndef 2ceciestuntest}
      WriteLn('Second: NOT Defined.');
    {$else}
      WriteLn('Second: Defined.');
    {$endif}
     
    {$ifdef 47ceciestimpossible}
      WriteLn('Impossible Defined.');
    {$endif}
    {$ifndef 47ceciestimpossible}
      WriteLn('Impossible NOT Defined.');
    {$endif}
     
    end.
    Defined.
    Second: Defined.
    Impossible NOT Defined.
    On a bien :

    - le résultat attendu pour le symbol name '2ceciestuntest', à savoir défini au sein du programme. En commentant le "define" correspondant, on obtient également le résultat attendu (non défini dans les 2 tests),

    - le résultat attendu pour le symbol name '47ceciestimpossible', à savoir (uniquement) non défini au sein du programme (en le définissant, on obtient également le résultat attendu).

  8. #8
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 132
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Yep !

    J'ai fait plus court et plus visuel, et bien rassurant aussi, ouf !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    {.$DEFINE 2027}
    procedure TForm1.FormCreate(Sender: TObject);
    begin
    {$IFDEF 2027}
      ShowMessage('Starting Nuclear War...');
    {$ENDIF}
    {$IFNDEF 2027}
      ShowMessage('Peace and love, brothers''n''sisters');
    {$ENDIF}
    Et selon que je mets le point "." entre { et $ ou pas, le DEFINE est défini ou pas, et heureusement ! : je n'ai qu'un ShowMessage, l'un ou l'autre en fonction du point, malgré un affichage bien trompeur.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Conception] Comment sont chargées les données dans les jeux?
    Par drcd dans le forum Développement 2D, 3D et Jeux
    Réponses: 15
    Dernier message: 24/10/2006, 15h09
  2. [c#] Comment sont gérés les noms de DataTable dans un DataSet ?
    Par Seth77 dans le forum Accès aux données
    Réponses: 4
    Dernier message: 10/09/2006, 19h02
  3. comment sont stoquées les données
    Par Biosox dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 12/01/2006, 09h17
  4. Comment sont programmés les plug-ins de jeux
    Par Marneus dans le forum Développement 2D, 3D et Jeux
    Réponses: 2
    Dernier message: 25/11/2005, 18h01
  5. Réponses: 2
    Dernier message: 02/08/2005, 13h53

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