I ask because my compiler seems to think so, even though I don’t.
echo \'int main;\' | cc -x c - -Wall
echo \'int main;\' | c++ -x c++ - -Wall
It is a warning as it is not technically disallowed. The startup code will use the symbol location of "main" and jump to it with the three standard arguments (argc, argv and envp). It does not, and at link time cannot check that it's actually a function, nor even that it has those arguments. This is also why int main(int argc, char **argv) works - the compiler doesn't know about the envp argument and it just happens not to be used, and it is caller-cleanup.
As a joke, you could do something like
int main = 0xCBCBCBCB;
on an x86 machine and, ignoring warnings and similar stuff, it will not just compile but actually work too.
Somebody used a technique similar to this to write an executable (sort of) that runs on multiple architectures directly - http://phrack.org/issues/57/17.html#article . It was also used to win the IOCCC - http://www.ioccc.org/1984/mullender/mullender.c .