At a given location in the executable code of a function member, a variable is said to be definitely assigned if the compiler can prove, by static flow analysis, that the variable has been automatically initialized or has been the target of at least one assignment. The rules of definite assignment are:
The definite assignment state of instance variables of a struct-type variable are tracked individually as well as collectively. In additional to the rules above, the following rules apply to struct-type variables and their instance variables:
Definite assignment is a requirement in the following contexts:
return
statement or through execution reaching the end of the function member body). This ensures that function members do no return undefined values in output parameters, thus enabling the compiler to consider a function member invocation that takes a variable as an output parameter equivalent to an assignment to the variable.this
variable of a struct-type constructor must be definitely assigned at each location where the constructor returns.The following example demonstrates how the different blocks of a try
statement affect definite assignment.
class A { static void F() { int i, j; try { // neither i nor j definitely assigned i = 1; // i definitely assigned j = 2; // i and j definitely assigned } catch { // neither i nor j definitely assigned i = 3; // i definitely assigned } finally { // neither i nor j definitely assigned i = 4; // i definitely assigned j = 5; // i and j definitely assigned } // i and j definitely assigned } }
The static flow analysis performed to determine the definite assignment state of a variable takes into account the special behavior of the &&
, ||
, and ?:
operators. In each of the methods in the example
class A { static void F(int x, int y) { int i; if (x >= 0 && (i = y) >= 0) { // i definitely assigned } else { // i not definitely assigned } // i not definitely assigned } static void G(int x, int y) { int i; if (x >= 0 || (i = y) >= 0) { // i not definitely assigned } else { // i definitely assigned } // i not definitely assigned } }
the variable i
is considered definitely assigned in one of the embedded statements of an if statement but not in the other. In the if
statement in the F
method, the variable i
is definitely assigned in the first embedded statement because execution of the expression (i = y)
always precedes execution of this embedded statement. In contrast, the variable i
is not definitely assigned in the second embedded statement since the variable i
may be unassigned. Specifically, the variable i
is unassigned if the value of the variable x
is negative. Similarly, in the G
method, the variable i
is definitely assigned in the second embedded statement but not in the first embedded statement.