It is very important that you do not turn interrupts until after you have completely initialized all necessary variables. If you don't do this, you will have very random behavior in your programs. Just about anything is possible:
Here's a more concrete example that I have seen in the code from two different students. This is from Lab 8 where you build at task scheduler. For the task scheduler, you have a task struct that contains several variables. One of these variables is a function pointer that points to the tick method that the task scheduler will invoke when the proper time arrives. If you do not initialize this function pointer before invoking it, you will jump to some undefined location and the processor will begin to execute whatever it finds (even data as most instructions are indistinguishable from data). In the student's code, the code looks like this, from the TimerISR():
The TimerISR code is fine, just note that it does dereference a function pointer:
tasks[i].state = tasks[i].TickFct(tasks[i].state);
The problem is in main() (see the excerpt below):
Look closely and you will see that the timer is turned on at the start of the code but the task struct has not been initialized yet. If you are lucky, the task structs will get initialized before the first interrupt occurs. Or, when you jump to some random location, it does something harmless. If you are unlucky, the task structs will not be initialized before the interrupt fires and you will jump to someplace random when the TimerISR is executed.