[VB6] Bug dans la gestion de ByRef et ByVal ?

Bug dans la gestion de ByRef et ByVal ? [VB6] - VB/VBA/VBS - Programmation

Marsh Posté le 17-02-2005 à 12:01:41    

En parcourant mon code pour y faire des modifications, je viens de m'apparcevoir d'un bug dans mon code, mais qui n'affecte pas le fonctionnement.
 
En effet, je travaille dans une DLL.
 
J'ai une pméthode définie de la sorte !:
 

Code :
  1. Public Function Test(ByVal myObj as clsObj) as Bolean
  2. On Error Goto GestErr:
  3.    myObj.loadById(Me.id)
  4.    Test = True
  5.    Exit Function
  6. GestErr:
  7.    Test = False
  8.    Me.strError = "Erreur lors du chargement de l'objet"
  9. End Function


 
Depuis l'ASP :
 

Code :
  1. Dim toto, titi
  2. Set toto = Server.CreateObject("myProject.myObj" )
  3. Set titi = Server.CreateObject("myProject.myTest" )
  4. titi.id = 1
  5. if titi.Test(toto) then
  6.     Response.Write toto.name
  7. else
  8.     Response.Write titi.strError
  9. end if


 
Etrange que ça marche, puisque je passe l'objet "toto" BYVAL et non BYREF, donc en sortie de fonction, il ne devrait pas être modifié !

Reply

Marsh Posté le 17-02-2005 à 12:01:41   

Reply

Marsh Posté le 17-02-2005 à 12:04:09    

C'est donc que tu n'as pas compris le fonctionement de ByVal et ByRef ;)

Reply

Marsh Posté le 17-02-2005 à 12:04:23    

Si tu attends 30 minutes, je peux te pondre un speech explicatif

Reply

Marsh Posté le 17-02-2005 à 12:32:31    

Non, la seule explication que je vois, c'est que VB gère ByRef les objets, même si on utilise ByVal.
 
Le ByRef et ByVal, c'est juste un renomage de "input" et "input output" qu'on trouvé en ADA ou T-SQL.
Dans le premier cas, on recopie la variable dans le scope local à la fonction, et donc, toute modification qu'on lui apporte est perdue à la sortie (avec le flag input, c'est d'ailleurs mieu, parcequ'une variable de ce type sera vue comme une constante dans la fonction, donc readonly, alors qu'en VB, on peut la modifier, et on se demande encore plusieurs jours après pourquoi le programme marche pas).
 
Quand à "input output", on passe le pointeur nommé à la fonction, donc la variable est manipulable depuis la fonction, directement à l'intérieur du scope appelant, ce qui fait que si on modifie la variable, en sortie elle l'est.
 
Y'a aucune raison pour que ça ne s'applique pas aux objets.

Reply

Marsh Posté le 17-02-2005 à 12:48:47    

En fait, faut déjà voir avec les types valeurs et les types références.
 
1) Types valeurs (Integer, Long, Short, etc.)
 
Avec ByVal, une copie de la variable est envoyée, donc la modifier dans la fonction ne la modifie pas à l'extérieur de la fonction.
 
Avec ByRef, c'est un pointeur sur la variable, donc la modifier dans la fonction la modifie à l'extérieur
 
2) Types références (String, et tout ce qui est objet)
 
Avec ByVal, On envoie un pointeur sur l'objet. On peut modifier les propriétés de l'objet, mais on ne peut l'assigner à un nouveau. Donc on pourra faire genre objet.propriété = pouet, ça modifera l'objet à l'extérieur. Par contre, un objet = New Bidule() n'aura aucune conséquence à l'extérieur de la fonction. Même chose pour les String, un pouet = "prout", équivalent à pouet = New String("prout" ), n'aura évidemment aucun effet à l'extérieur.
 
Avec ByRef, c'est un pointeur sur un pointeur, donc pour pourra faire objet = New Bidule(), ça modifira l'objet à l'extérieur de la fonction :)

Reply

Marsh Posté le 17-02-2005 à 14:44:47    

c bien ce que je dis, c'est un "bug" d'implémentation de byval/byref.
 
cette limitation vient simplement du faite que VB fait connement ça recopie sans regarde ce qu'il recopie. recopier un pointeur, ça sert à rien, du coup le ByVal se comporte comme le ByRef pour un type "1".
 
après, ce que permet de type "2" avec le byref, je ne suis pas sûr de saisir l'intérêt.

Reply

Marsh Posté le 18-02-2005 à 10:00:06    

C'est pas un bug ;) C'est comme ça que ça marche :(
 
Après oui y'a cette différence avec les types 1 et 2.
 
Pour le type 2 et ByRef, ça permet de créer un objet, genre :

Code :
  1. Public Sub CreateObject(ByRef obj as Pouet)
  2.   obj = New Pouet()
  3. End Sub

Ce qui est de toute manière déconseillé. Donc de manière générale, c'est rare qu'on utilise le ByRef avec le type 2 :/

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed