During the initialization routine of my code I use to do such things as:
clr r0 ; will always stay zero
out PORTA, r0; initialize ports out DDRA, r0 out PORTB, r0 ...
Is this actually necessary? Or can I be sure this is automatically done upon reset? Especially, can I rely on all ports to be set as inputs by default so there is no problem with external votages when no code is executed?
The I/O ports of an AVR are set to INPUT / Tri-State / Hi-Z (DDRx = 0x00) upon reset. Most microcontrollers (if not all?) have this behavior. It's the safest state for a pin to be in. So yes, you can rely on the ports to be set automatically as inputs.
Some excerpts an the ATmega16 show exactly that: