A return from the main program does not call the exit function, but simply returns to the start file crt0. In the standard version of crt0 a return from main is followed by code to execute any static destructors and a jump to the program entry point, where the program will restart.
Note that crt0 may be customized to offer more appropriate behavior for the application.