c# - Why do local variables require initialization, but fields do not? -


if create bool within class, bool check, defaults false.

when create same bool within method, bool check(instead of within class), error "use of unassigned local variable check". why?

yuval , david's answers correct; summing up:

  • use of unassigned local variable bug, , can detected compiler @ low cost.
  • use of unassigned field or array element less bug, , harder detect condition in compiler. therefore compiler makes no attempt detect use of uninitialized variable fields, , instead relies upon initialization default value in order make program behavior deterministic.

a commenter david's answer asks why impossible detect use of unassigned field via static analysis; point want expand upon in answer.

first off, variable, local or otherwise, in practice impossible determine exactly whether variable assigned or unassigned. consider:

bool x; if (m()) x = true; console.writeline(x); 

the question "is x assigned?" equivalent "does m() return true?" now, suppose m() returns true if fermat's last theorem true integers less eleventy gajillion, , false otherwise. in order determine whether x assigned, compiler must produce proof of fermat's last theorem. compiler not smart.

so compiler instead locals implements algorithm fast, , overestimates when local not assigned. is, has false positives, says "i can't prove local assigned" though , know is. example:

bool x; if (n() * 0 == 0) x = true; console.writeline(x); 

suppose n() returns integer. , know n() * 0 0, compiler not know that. (note: c# 2.0 compiler did know that, removed optimization, specification not say compiler knows that.)

all right, know far? impractical locals exact answer, can overestimate not-assigned-ness cheaply , pretty result errs on side of "make fix unclear program". that's good. why not same thing fields? is, make definite assignment checker overestimates cheaply?

well, how many ways there local initialized? can assigned within text of method. can assigned within lambda in text of method; lambda might never invoked, assignments not relevant. or can passed "out" anothe method, @ point can assume assigned when method returns normally. clear points @ local assigned, , right there in same method local declared. determining definite assignment locals requires local analysis. methods tend short -- far less million lines of code in method -- , analyzing entire method quite quick.

now fields? fields can initialized in constructor of course. or field initializer. or constructor can call instance method initializes fields. or constructor can call virtual method initailizes fields. or constructor can call method in class, might in library, initializes fields. static fields can initialized in static constructors. static fields can initialized other static constructors.

essentially initializer field anywhere in entire program, including inside virtual methods declared in libraries haven't been written yet:

// library written barcorp public abstract class bar {     // derived class responsible initializing x.     protected int x;     protected abstract void initializex();      public void m()      {         initializex();        console.writeline(x);      } } 

is error compile library? if yes, how barcorp supposed fix bug? assigning default value x? that's compiler already.

suppose library legal. if foocorp writes

public class foo : bar {     protected override void initializex() { }  } 

is that error? how compiler supposed figure out? way whole program analysis tracks initialization static of every field on every possible path through program, including paths involve choice of virtual methods @ runtime. problem can arbitrarily hard; can involve simulated execution of millions of control paths. analyzing local control flows takes microseconds , depends on size of method. analyzing global control flows can take hours because depends on complexity of every method in program , libraries.

so why not cheaper analysis doesn't have analyze whole program, , overestimates more severely? well, propose algorithm works doesn't make hard write correct program compiles, , design team can consider it. don't know of such algorithm.

now, commenter suggests "require constructor initialize fields". that's not bad idea. in fact, such not-bad idea c# has feature structs. struct constructor required definitely-assign fields time ctor returns normally; default constructor initializes fields default values.

what classes? well, how know constructor has initialized field? ctor call virtual method initialize fields, , in same position in before. structs don't have derived classes; classes might. library containing abstract class required contain constructor initializes fields? how abstract class know values fields should initialized to?

john suggests prohibiting calling methods in ctor before fields initialized. so, summing up, our options are:

  • make common, safe, used programming idioms illegal.
  • do expensive whole-program analysis makes compilation take hours in order bugs aren't there.
  • rely upon automatic initialization default values.

the design team chose third option.


Comments

Popular posts from this blog

facebook - android ACTION_SEND to share with specific application only -

python - Creating a new virtualenv gives a permissions error -

javascript - cocos2d-js draw circle not instantly -