The larger reason for not debugging with printf() is that it is usually inefficient, inadequate, and unnecessary.
Inefficient: printf() and kin use a lot of flash and RAM relative to what's available on a small microcontroller, but the bigger inefficiency is in the actual debugging. Changing what's being logged requires recompiling and reprogramming the target, which slows down the process. It also uses up a UART that you could otherwise be using to do useful work.
Inadequate: There's only so much detail you can output over a serial link. If the program hangs, you don't know exactly where, just the last output that completed.
Unnecessary: Many microcontrollers can be remotely debugged. JTAG or proprietary protocols can be used to pause the processor, peek at registers and RAM, and even alter the state of the running processor without having to recompile. This is why debuggers are generally a better way of debugging than print statements, even on a PC with tons of space and power.
It's unfortunate that the most common microcontroller platform for newbies, Arduino, doesn't have a debugger. The AVR supports remote debugging, but Atmel's debugWIRE protocol is proprietary and undocumented. You can use an official dev board to debug with GDB, but if you have that you're probably not too worried about Arduino anymore.