Manuel de suivi dynamique Solaris

Variables locales de clause

Vous pouvez également définir les variables en D dont le stockage est réutilisé pour chaque clause du programme en D. Les variables locales de clause sont similaires aux variables automatiques des programmes en langage C, C++ ou Java actifs pendant chaque invocation d'une fonction. Comme toutes les variables de programme en D, les variables locales de clause sont créées à leur première affectation. Vous pouvez référencer et affecter ces variables en appliquant l'opérateur -> à l'identificateur spécial this :

BEGIN
{
	this->secs = timestamp / 1000000000;
	...
}

Si vous souhaitez déclarer de manière explicite une variable locale de clause avant de l'utiliser, vous pouvez le faire à l'aide du mot-clé this :

this int x;   /* an integer clause-local variable */
this char c;  /* a character clause-local variable */

BEGIN
{
	this->x = 123;
	this->c = 'D';
}

Les variables locales de clause ne sont actives que pendant la durée de vie d'une clause de sonde donnée. Une fois que DTrace a exécuté les actions liées à ces clauses pour une sonde donnée, le stockage de toutes les variables locales de clause est récupéré et réutilisé pour la clause suivante. C'est pourquoi les variables locales de clause constituent les seules variables en D à ne pas contenir initialement que des zéros. Notez que si votre programme contient plusieurs clauses pour une seule sonde, toutes les variables locales de clause resteront intactes lors de l'exécution des clauses, comme illustré dans l'exemple suivant :


Exemple 3–2 clause.d : variables locales de clause

int me;			/* an integer global variable */
this int foo;		/* an integer clause-local variable */

tick-1sec
{
	/*
	 * Set foo to be 10 if and only if this is the first clause executed.
	 */
	this->foo = (me % 3 == 0) ? 10 : this->foo;
	printf("Clause 1 is number %d; foo is %d\n", me++ % 3, this->foo++);
}

tick-1sec
{
	/*
	 * Set foo to be 20 if and only if this is the first clause executed. 
	 */
	this->foo = (me % 3 == 0) ? 20 : this->foo;
	printf("Clause 2 is number %d; foo is %d\n", me++ % 3, this->foo++);
}

tick-1sec
{
	/*
	 * Set foo to be 30 if and only if this is the first clause executed.
	 */
	this->foo = (me % 3 == 0) ? 30 : this->foo;
	printf("Clause 3 is number %d; foo is %d\n", me++ % 3, this->foo++);
}

Comme les clauses sont toujours exécutées dans l'ordre du programme et que les variables locales de clause sont persistantes à travers les différentes clauses activant la même sonde, l'exécution du programme ci-dessus entraîne toujours la même sortie :


# dtrace -q -s clause.d
Clause 1 is number 0; foo is 10
Clause 2 is number 1; foo is 11
Clause 3 is number 2; foo is 12
Clause 1 is number 0; foo is 10
Clause 2 is number 1; foo is 11
Clause 3 is number 2; foo is 12
Clause 1 is number 0; foo is 10
Clause 2 is number 1; foo is 11
Clause 3 is number 2; foo is 12
Clause 1 is number 0; foo is 10
Clause 2 is number 1; foo is 11
Clause 3 is number 2; foo is 12
^C

Alors que les variables locales de clause sont persistantes à travers les clauses activant la même sonde, leurs valeurs restent indéfinies dans la première clause exécutée pour une sonde donnée. Veillez à affecter chaque variable locale de clause à une valeur appropriée avant de l'utiliser ou votre programme risque de produire un résultat inattendu.

Vous pouvez définir les variables locales de clause à l'aide de n'importe quel type de variable scalaire mais pas les tableaux associatifs au moyen d'une étendue locale de clause. L'étendue des variables locales de clause ne s'applique qu'aux données de variable correspondantes et non à l'identité du nom et du type définie dans la variable. Après avoir défini une variable locale de clause, vous pouvez utiliser le nom et la signature de type correspondants dans n'importe quelle clause de programme en D ultérieure. Vous ne pouvez pas espérer que l'emplacement de stockage soit le même entre les différentes clauses.

Vous pouvez utiliser des variables locales de clause pour accumuler des résultats intermédiaires de calculs ou comme copies temporaires d'autres variables. Il est plus rapide d'accéder à une variable locale de clause qu'à un tableau associatif. Par conséquent, si vous devez référencer à plusieurs reprises une valeur de tableau associatif dans la même clause d'un programme en D, vous gagnerez en efficacité en la copiant dans une variable locale de clause, puis en référençant cette dernière à plusieurs reprises.