If any member of the exec family of functions succeeds, it replaces the current process image with a new executable process. There is no return from that new image because the old image is gone.
But, if the exec fails it will usually return and you can look at the return code and the value assigned to errno to find out what went wrong, run printf as many times as you want, and continue processing with whatever code you want to run. Some exec failures can't be detected until the old process image has been destroyed -- in those cases, there is no return from the exec .