6

Each program has a main() and the program execution starts from there. Is it possible to write a program without main()and make another function as the entry point? If so, can any one please tell me how can that be done? I am using Linux?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Manu
  • 5,534
  • 6
  • 32
  • 42
  • 7
    What are you trying to accomplish by not having `main` as your entry point? – eduffy Mar 13 '12 at 01:55
  • 1
    @eduffy was reading a book on C where it had mention main() is just a function as many other functions so got this doubt, – Manu Mar 14 '12 at 04:48
  • Check out this article, http://linuxgazette.net/issue84/hawk.html, to see what happens before `main()` is called. – eduffy Mar 14 '12 at 13:04
  • Check [here](https://stackoverflow.com/questions/29694564/what-is-the-use-of-start-in-c). You can also go crazy and write your own assembly, if you want to have fun. – Jay-Pi Jul 27 '20 at 03:24

3 Answers3

6

If you're compiling with gcc, specifying -e <symbol> option will let you change the entry point to a function symbol().

George Skoptsov
  • 3,831
  • 1
  • 26
  • 44
  • 2
    This will likely badly break things since it will bypass startup code that the standard library will assume has already run... – R.. GitHub STOP HELPING ICE Mar 13 '12 at 02:07
  • 3
    Sure, but this answers the question "is it possible to write a function without main() and make other function as entry point ? if so can any one pls tell me how can tht be done. I am using linux", not "how can I change the entry point to a C program and avoid breaking things badly". – George Skoptsov Mar 13 '12 at 02:14
  • Fair enough. It's more a comment to OP not to do this than a critique of your answer. – R.. GitHub STOP HELPING ICE Mar 13 '12 at 02:21
0

You can do this in a portable way, simply by including this header file in your main program:

int nomDePlume(int argc, char *argv[]);
int main(int argc, char *argv[]) { return nomDePlume(argc, argv); }

Then provide your own variant of main:

int nomDePlume(int argc, char *argv[]) {
    weaveYourMagic();
    return 42;
}

That doesn't actually change the entry point of the executable (something that's very much implementation specific) but it does let you call your program entry point whatever you wish (within the bounds of legal identifiers, of course).


If you don't want a main at all (even in a header file), it becomes a little tricky.

That's because the entry pount for an executable generally isn't main - there's quite a bit of activity happening before main is called, to do with environment setup and other things (and some tear-down stuff after main exits, such as your atexit handlers).

In other words, while the main function may be where your C program starts, that's not the same thing as where your executable starts.

As one example, in Linux, the ELF executable format contains an entry point address in the e_entry field of a header block, and that's where the program loader jumps to when it's ready to run the executable.

What usually happens to set this up is that you link (implicitly) with some start-up code like crt0 and the linker populates the e_entry field with the address of a known symbol. An example of which is (from that link, with comments slightly modified):

.text
.globl _start
_start:                       # Entry point known to linker.
    xor %ebp, %ebp            # RBP <- 0, mark end of stack frames.
    mov (%rsp), %edi          # Get argc from stack (implicitly
                              #   zero-extended to 64-bit).
    lea 8(%rsp), %rsi         # Take address of argv from stack.
    lea 16(%rsp,%rdi,8), %rdx # Take address of envp from stack.
    xor %eax, %eax            # Per ABI and compatibility with icc.

    call main                 # Three args %edi/%rsi/%rdx (first
                              #   two are C standard).

    mov %eax, %edi            # Effectively set up _exit(main()).
    xor %eax, %eax            # Per ABI and compatibility with icc.
    call _exit                # Terminate the program.

You can see there the start-up and tear-down stuff happening on either side of the main call, and therein lies a possible solution for you.

By creating your own crt0, replacing the text main with whatever you want to call, and ensuring the linker uses your crt0 rather than the default one, you can have it call whatever function you want to provide as the main one.


However, it's not really clear what you gain from being able to use an arbitrarily-named main function, other than to obtain job security or annoy your colleague when they can't find where your code begins :-)

If it's an educational thing, that's fine - I just wouldn't do this in a real-world situation.

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
-1

There is a solution for build executable shared library that you can build a program use another function as entry point.

The code looks like:

#include <stdio.h>
#include <stdlib.h>
const char __invoke_dynamic_linker[] __attribute__ ((section (".interp"))) 
    = "/lib/ld-linux.so.2";
void fun()
{
    printf("This is fun./n");
    exit(0);
}

Then build your program as an shared library and specify func as entry point:

$ gcc -fpic -shared -o fun.so -Wl,-e,fun fun.c
$ ./fun.so

The problem of this way is that the func can't have the normal arguments as we have in main function, this is because we don't have the c library to initialize the main arguments stuff.

Sam Liao
  • 43,637
  • 15
  • 53
  • 61
  • Your suggestion seems even more vague than the question. Do you mean to say that the entry function should be in a dynamically linked library, so that its address can be looked up by name? – George Skoptsov Mar 13 '12 at 02:31
  • @GeorgeSkoptsov it needs not to be a dynamically linked library, it could be in the program itself only if you need not remove the symbols info or you can hard code to compares the argument with some known functions symbols. I think Manu just want the program to call different functions. – Sam Liao Mar 13 '12 at 02:51