Handbuch zur dynamischen Ablaufverfolgung in Solaris

Klausel-lokale Variablen

Es besteht auch die Möglichkeit, D-Variablen zu deklarieren, deren Speicherbereich für jede D-Programmklausel wieder verwendet wird. Klausel-lokale Variablen sind mit automatischen Variablen in C-, C++- oder Java-Programmen vergleichbar, die während jedes Aufrufs einer Funktion aktiv sind. Wie alle anderen D-Programmvariablen werden auch klausel-lokale Variablen bei ihrer ersten Zuweisung erzeugt. Diese Variablen werden durch Anwendung des Operators -> auf den speziellen Bezeichner this referenziert und zugewiesen:

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

Wenn Sie eine klausel-lokale Variable vor ihrer Verwendung explizit deklarieren möchten, greifen Sie hierzu auf das Schlüsselwort this zurück:

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

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

Klausel-lokale Variablen sind nur während der Lebensdauer der jeweiligen Prüfpunktklausel aktiv. Wenn DTrace die Aktionen der Klauseln für einen bestimmten Prüfpunkt durchgeführt hat, wird der Speicherbereich aller klausel-lokalen Variablen zurückgefordert und für die nächste Klausel verwendet. Deshalb werden klausel-lokale Variablen im Gegensatz zu allen anderen D-Variablen anfänglich nicht mit Nullen angefüllt. Wenn ein Programm mehrere Klauseln für denselben Prüfpunkt enthält, bleiben alle klausel-lokalen Variablen intakt, solange die Klauseln ausgeführt werden. Das folgende Beispiel verdeutlicht dieses Prinzip:


Beispiel 3–2 clause.d: Klausel-lokale Variablen

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++);
}

Da die Klauseln immer in der Programmreihenfolge ausgeführt werden und klausel-lokale Variablen in unterschiedlichen Klauseln zur Aktivierung desselben Prüfpunkts bestehen, ergibt die Ausführung des obigen Programms stets dieselbe Ausgabe:


# 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

Während klausel-lokale Variablen über die Klauseln hinweg beständig sind, die denselben Prüfpunkt aktivieren, sind deren Werte in der als Erste für einen Prüfpunkt ausgeführten Klausel nicht definiert. Denken Sie daran, jeder klausel-lokalen Variable vor ihrer Verwendung einen geeigneten Wert zuzuweisen. Anderenfalls bringt das Programm möglicherweise unerwartete Resultate.

Klausel-lokale Variablen können mit jedem skalaren Variablentyp definiert werden. Eine Definition von assoziativen Vektoren mit klausel-lokalem Gültigkeitsbereich ist jedoch nicht möglich. Der Gültigkeitsbereich klausel-lokaler Variablen bezieht sich nur auf die entsprechenden Variablendaten, nicht aber auf den für die Variable definierten Namen oder ihre Typidentität. Die Namens- und Typensignatur einer definierten klausel-lokalen Variable kann in jeder nachfolgenden D-Programmklausel verwendet werden. Es besteht keine Garantie, dass der Speicherbereich über die verschiedenen Klauseln hinweg identisch ist.

Klausel-lokale Variablen können zum Ansammeln von Zwischenergebnissen bei Berechnungen oder als temporäre Kopien anderer Variablen eingesetzt werden. Der Zugriff auf eine klausel-lokale Variable läuft wesentlich schneller ab als der Zugriff auf einen assoziativen Vektor. Wenn Sie also den Wert eines assoziativen Vektors in derselben D-Programmklausel mehrmals referenzieren müssen, erweist es sich als effizienter, den Wert zuerst in eine klausel-lokale Variable zu kopieren und die lokale Variable dann wiederholt zu referenzieren.