..................

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

gnozal a écrit :
Dobro a écrit :@Gnozal ;: oui effectivement ça marche le static

mais tu admettra que la fonction Defined()
a un comportement etrange :)
Non, pas vraiment.
Defined() intervient au moment de la compilation, pas lors de l'exécution.
j'y est pensé apres coup ;)

le typage des variables a lieu avant l'utilisation de celle ci au moment de la compile

c'est d'ailleurs pour ça qu'on type la variable AVANT utilisation

c'est pourquoi Defined() ne peux pas considerer le Global de DIM()
puisque celui-ci (le typage) est defini apres Defined() !

le global prends action apres le premier DIM()
mais defined() lui l'ignore

il faudrai une compillation en plusieur passe , pour que ce cas soit pris en compte , je pense ... :)

si cela avait fonctionner hors procédure déjà?
j'aurai poursuivi avec les tests en procédure,
il me semble?
oui mais si tu avait lu depuis le debut
tu aurai vu que nous cherchions surtout a le faire fonctionner DANS la procedure , en dehors, on s'en fou ! c'etait pas le sujet :)

quand a tes intentions, je les ignores, je me contente de lire ce que tu ecris ;)

ps : j'ai reagis face a ces propos :
defined() détecte bien le tableau? mais lorsque que celui à été crée en amont.

Avec le second exemple de @PAPIPP le test fonctionne en mettant le tableau en début de programme!
mince alors!
ou tu dis une evidence
defined() détecte bien le tableau? mais lorsque que celui à été crée en amont.
encore heureux que ça fonctionne :)

et ou tu dit que le Second code de PAPIPP fonctionne

ben oui , puisque ça se passe hors procedure , et que notre probleme
soulevait un dysfonctionnnement DANS la procedure ;)
Avatar de l’utilisateur
kernadec
Messages : 1606
Inscription : ven. 25/avr./2008 11:14

Message par kernadec »

merci, Dobro
je comprend ta démarche,
mais comme toi, j'ai cru à un dysfonctionnement de la fonction defined()
voila pourquoi, j'ai d'abord chercher dans le global.
j'avais bien compris l' importance que cela fonctionne dans une procédure.

cordialement
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Message par Backup »

l'essentiel c'est qu'il vaut mieux utiliser 'Static'
pour ce genre de chose :)
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Message par PAPIPP »

Bonjour à tous
Je viens de réaliser quelques tests comme le montre le prg ci-dessous
Essayez le prg comme il est actuellement et en suite comme l'encadré
le demande placez la ligne Global Dim TestArray(20) dans l'encadré en commentaire et voyez les résultats
si l'on place cette ligne en commentaire bien que le tableau TestArray soit vu comme étant défini par le compilateur
le tableau TestArray n'est pas initialisé ce qui provoque une erreur invalid memory bug ou pas ????
Le compilateur détecte la définition du tableau alors que pendant l'éxécution ce même tableau n'est pas encore initialisé
Ainsi placée la procédure en tête du prg ou en fin ne donne pas les mêmes résultats
par contre l'option declare n'a aucune influence sur la détection de la définition mais est indispensable si l'on place la proc en fin
Autre remarque ; dans la procedure deb_d si l'on place Defined(TestArray, #PB_Array) dans la procédure on n'obtient pas les mêmes
résultats que si on la place au moment de l'appel comme c'est le cas actuellement !!!
C'est bien le compilateur qui dit si une zone est définie ou pas en fonction de l'endroit où cela est demandé et par rapport
à l'endroit ou cette zone est définie si la demande est faite séquentiellement(ligne après ligne) après une définition
le compilateur la voit comme définie même si cela n'est pas le cas
exemple avec la ligne global ci-dessous en commentaire la définition dans la procédure toto est vu comme étant réalisée !!
En conséquence :
il est dangereux d'utiliser cette fonction pour initialiser un prg ou une proc


Code : Tout sélectionner

Global msg$
Procedure ErrorHandler()
msg$+"Erreur lgn="+Str(ErrorLine())+Chr(10)
msg$+ErrorMessage(ErrorCode())+Chr(10)

;   #PB_OnError_InvalidMemory         : Lecture ou écriture dans une zone protégée.
;   #PB_OnError_Floatingpoint         : Erreur de calcul flottant.
;   #PB_OnError_Breakpoint            : Point d'arrêt débogueur atteint (autres que ceux du PureBasic).
;   #PB_OnError_IllegalInstruction    : Exécution d'une instruction invalide.
;   #PB_OnError_PriviledgedInstruction: Exécution d'une instruction privilégiée (system-) non autorisée.
;   #PB_OnError_DivideByZero          : Division par zéro (Windows seulement).       

Select  ErrorCode()
Case #PB_OnError_InvalidMemory 
msg$+"Lecture ou écriture dans une zone protégée."
Case #PB_OnError_Floatingpoint 
  msg$+"Erreur de calcul flottant."
Case   #PB_OnError_Breakpoint
msg$+"Point d'arrêt débogueur atteint (autres que ceux du PureBasic)"
Case   #PB_OnError_IllegalInstruction
msg$+"Exécution d'une instruction invalide."
Case   #PB_OnError_PriviledgedInstruction
msg$+" Exécution d'une instruction privilégiée (system-) non autorisée."
Case    #PB_OnError_DivideByZero 
msg$+" Division par zéro (Windows seulement)"
EndSelect
       
MessageRequester("Essai defined sur erreur ", msg$,#PB_MessageRequester_Ok )
  EndProcedure
Procedure deb_d(val,pb_compil_lgn)
;   Debug  "Defined(TestArray, #PB_Array)"+Str(Defined(TestArray, #PB_Array))+" lgn="+Str(PB_Compil_Lgn)
;   msg$+   "Defined(TestArray, #PB_Array)"+Str(Defined(TestArray, #PB_Array))+" lgn="+Str(PB_Compil_lgn)+Chr(10)
  Debug  "Defined(TestArray, #PB_Array)"+Str(val)+" lgn="+Str(PB_Compil_Lgn)
  msg$+   "Defined(TestArray, #PB_Array)"+Str(val)+" lgn="+Str(PB_Compil_lgn)+Chr(10)

EndProcedure
 OnErrorCall(@ErrorHandler())
deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
Declare toto()

deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
;******************  ici soit appel toto() soit placez la proc toto  en tête ou en fin *************************
; toto()
Procedure toto()
  msg$+"***interne proc ***"+Chr(10)
  Debug "***interne proc ***"
  deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
   CompilerIf Defined(TestArray, #PB_Array) = #False
      deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
      Global Dim TestArray(20)
      TestArray(0) +20
      deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
   CompilerEndIf
      deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
      TestArray(10) +30
      msg$+Str(Testarray(0))+Chr(10)
      msg$+Str(Testarray(10))+Chr(10)
      Debug Str(Testarray(0))
      Debug Str(Testarray(10))
EndProcedure

deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
;*********************************************************************************************************************************
;**
;** Pour voir la différence placer en ou or commentaire la ligne Global suivante  **********
;** si l'on place la ligne suivante en commentaire bien que le tableau TestArray soit vu comme étant défini par le compilateur
;** le tableau TestArray n'est pas initialisé ce qui provoque une erreur invalid memory  bug ou pas ????
;** Le compilateur détecte la définition du tableau alors que pendant l'éxécution ce même tableau n'est pas encore initialisé
;** Ainsi placée la procédure en tête du prg ou en fin ne donne pas les mêmes résultats 
;** par contre l'option declare n'a aucune influence sur la détection de la définition
;** Autre remarque ; dans la procedure deb_d si l'on place Defined(TestArray, #PB_Array) dans la procédure on n'obtient pas les mêmes
;**  résultats que si on la place au moment de l'appel comme c'est le cas actuellement !!!
;**  C'est bien le compilateur qui dit si une zone est définie ou pas en fonction de l'endroit où cela est demandé et par rapport
;** à l'endroit ou cette zone est définie si la demande est faite séquentiellement(ligne après ligne) après une définition 
;** le compilateur la voit  comme définie même si cela n'est pas le cas 
;** exemple avec la ligne global ci-dessous en commentaire la définition dans la procédure toto est vu comme étant réalisée !!
;**  En conséquence il est dangereux d'utiliser cette fonction pour initialiser un prg ou une proc
;** 
Global Dim TestArray(20)
;********************************************************************************************************************************* 
CompilerIf Defined(TestArray, #PB_Array) = #False
      Debug "Global Dim TestArray(20) "
      deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
      Global Dim TestArray(20)
      deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
      TestArray(0) +100
 CompilerElse 
      deb_d(Defined(TestArray, #PB_Array),#PB_Compiler_Line)
      TestArray(10) +230
      msg$+"**** dans le prg principal avant appel toto ****"+Chr(10)
      msg$+Str(Testarray(0))+Chr(10)
      msg$+Str(Testarray(10))+Chr(10)
      Debug "**** dans le prg principal avant appel toto ****"
      Debug Str(Testarray(0))
      Debug Str(Testarray(10))
   
 CompilerEndIf
 TestArray(0) +1
 TestArray(10) +10
msg$+"**** dans le prg principal avant appel toto mais après compilerif ****"+Chr(10)
msg$+Str(Testarray(0))+Chr(10)
msg$+Str(Testarray(10))+Chr(10)
Debug "**** dans le prg principal avant appel toto mais après compilerif ****"
Debug Str(Testarray(0))
Debug Str(Testarray(10))
For i=1 To 3
toto()
msg$+"**** dans le prg principal appel toto "+Str(i)+" ****"+Chr(10)
msg$+Str(Testarray(0))+Chr(10)
msg$+Str(Testarray(10))+Chr(10)
Debug "**** dans le prg principal appel toto "+Str(i)+" ****"
Debug Str(Testarray(0))
Debug Str(Testarray(10))
Next
MessageRequester("Essai defined", msg$,#PB_MessageRequester_Ok )
Je viens seulement de lire ce que Dobro avait écrit et je suis entièrement d’accord avec ce qui est dit
Pour les techniques d’initialisation il existe une autre manière d’initialiser qui vient des langages qui n’initialisent pas les données à la compile ASM COBOL FORTRAN
Dans le prg principal on initialise une variable qui regroupe par exemple sous_prg1=0 sous_prg2=0 sous_prg3=0 etc.. et on passe par adresse la variable contenant tous les flags propres à chaque sous_prg qui incrémente sa propre donnée (ou une autre s’il ne veut pas que cet autre sous_prg soit initialisé ) ou alors il lui donne une valeur x suivant ce que l’on veut faire Comme cette variable peut être lu soit du prg principal soit d’un autre sous_prg. On fait ce que l’on veut soit dans un sous_prg soit dans le prg principal .
Répondre