Let’s have a look at the generated assembly of your program:
.LC0:
.string "Hello World..."
.LC1:
.string "Successfully run without main..."
nomain:
push rbp
mov rbp, rsp
mov edi, OFFSET FLAT:.LC0
call puts
mov edi, OFFSET FLAT:.LC1
call puts
nop
pop rbp
ret
Note the ret
statement. Your program’s entry point is determined to be nomain
, all is fine with that. But once the function returns, it attempts to jump into an address on the call stack… that isn’t populated. That’s an illegal access and a segmentation fault follows.
A quick solution would be to call exit()
at the end of your program (and assuming C11 we might as well mark the function as _Noreturn
):
#include <stdio.h>
#include <stdlib.h>
_Noreturn void nomain(void)
{
printf("Hello World...\n");
printf("Successfully run without main...\n");
exit(0);
}
In fact, now your function behaves pretty much like a regular main
function, since after returning from main
, the exit
function is called with main
‘s return value.