In Visual Basic ci sono due modi per passare argomenti alle procedure: ByVal (per valore, copia) e ByRef (per riferimento, il vero oggetto o variabile). Se un parametro è contrassegnato come ByRef, qualsiasi modifica apportata all'interno della procedura si rifletterà sulla variabile originale al di fuori della procedura.
L'uso di ByRef è particolarmente rilevante quando è necessario restituire più risultati da una funzione o ottimizzare il lavoro con grosse strutture dati (senza copiarle).
Esempio:
Sub Swap(ByRef a As Integer, ByRef b As Integer) Dim temp As Integer = a a = b b = temp End Sub Dim x As Integer = 10 Dim y As Integer = 20 Swap(x, y) ' x = 20, y = 10
Domanda: «È possibile passare in sicurezza i tipi di dati semplici (Integer, String) per riferimento tra diversi thread?»
Risposta: No! Quando si passano variabili per riferimento (ByRef) tra thread possono sorgere condizioni di corsa (data races), poiché entrambe le procedure possono modificare la variabile in momenti diversi. Questo non è sicuro e può portare a bug difficili da individuare.
Esempio:
' In modalità multithreading, potrebbe verificarsi una situazione in cui i valori ' a e b vengono sostituiti in modo non corretto a causa dell'accesso simultaneo!
Storia:
In un vecchio prodotto finanziario utilizzavano
ByRefper passare contatori tra diversi moduli. Uno degli sviluppatori ha accidentalmente passato una espressione temporanea come riferimento in una funzione, anziché una variabile. Ciò ha causato un crash del programma, poiché un riferimento inesistente stava tentando di modificare un oggetto non inizializzato.
Storia:
Un sistema di calcolo ingegneristico passava array per riferimento per risparmiare memoria. Tuttavia, qualcuno ha modificato l'array all'interno di una procedura ausiliaria. Questo ha portato all'emergere di bug difficili da individuare: i dati venivano modificati al di fuori del contesto previsto.
Storia:
In un analizzatore di dati multithread, hanno tentato di "ottimizzare" il passaggio di stringhe per riferimento per velocizzare il lavoro. A causa del passaggio non sicuro delle stringhe per riferimento simultaneamente da più thread, sono emersi crash imprevedibili e il meccanismo di sincronizzazione si è rotto.