Actually avr-gcc is under the covers in Arduino as well... you just have to use C++-ish syntax if you're using their libraries or writing your own. Otherwise, the only constraint is that you are 'forced' to use the pattern equivalent to:
int main(int argc, char *argv[]){
setup();
for(;;){
loop();
}
return 0;
}
which is a pattern that fits a large cross-section (arguably the entirety) of embedded design. You just implement setup() and loop().
Also it's not a choice between Arduino and a micro-controller. In principle, you could take the ATMega328P out of an Arduino board context, programmed with a sketch, and transplant it into a more tightly integrated solution.
So I guess I disagree with the sentiment of some of the other answers here suggesting that Arduino is just a "toy" platform. In my opinion it's viable for more "serious" development. It just lowers the barrier to entry into the embedded world. The ability to program it without a separate programmer (e.g. AVRISP mkII, STK500, etc.) is kind of a big deal in this regard.
I don't really think that it demands significant compromise from more advanced users.