Well, it could.
For example, in the dialect of C used in the Plan 9 operating system
main is normally declared as a
void function, but the exit status is returned to the calling environment by passing a string pointer to the
exits() function. The empty string denotes success, and any non-empty string denotes some kind of failure. This could have been implemented by having
main return a
And it would certainly be possible to implement a system with a
double exit status.
int? It's just a matter of convention -- and there's a tremendous value in having operating systems and programs that run under them obey a common convention.
The Unix convention is to use an integer status code, with 0 denoting success and non-zero denoting failure (because typically there's only one way to succeed, but multiple ways to fail). I don't know whether that convention originated with Unix; I suspect it came from earlier operating systems.
Floating-point would be a more difficult convention, because (a) floating-point support is not universal, (b) it's more difficult to define a mapping between floating-point values and error conditions, (c) different systems use different floating-point representations, and (d) just imagine the fun of tracking down a rounding error in your program's exit status. Integers, on the other hand, lend themselves very well to enumerating error codes.
Plan 9, as I mentioned, uses strings, but that imposes some complexity for memory management, character encoding, etc. It was, as far as I know, a new idea when Plan 9 implemented it, and it didn't replace the existing widespread convention.
(Incidentally, in C++
main can only return
int, and in C
void main is permitted only if the compiler specifically supports it. Many compilers don't complain very loudly if you write
void main, but it's only a slight exaggeration to say that it's wrong.)