You'd use return whenever there's no compelling reason to use exit(). In C++ in particular, note that exit() does not return and objects on the stack of main() won't get destroyed. Compare:
Code:
#include <fstream>
#include <cstdlib>
int main()
{
std::ofstream os("out.txt");
os << "Hello, there!\n"; // Note the lack of flushing.
std::exit(0);
}
vs.
Code:
#include <fstream>
#include <cstdlib>
int main()
{
std::ofstream os("out.txt");
os << "Hello, there!\n"; // Note the lack of flushing.
// Implicit return 0.
}
I'm sure it would be fairly easy to find a platform where after running the first example, out.txt is empty. It would be hard to find one where the same holds for example two, and if you find one, then it's got a seriously broken iostreams implementation.
As for obtaining the returned value, that's highly system specific. DOS or Win32 cmd.exe would put it in the ERRORLEVEL system variable. Bash lets you fetch it with $?, or you can just use && or || or similar to act on it.