3

In C++, is it possible for main to be defined by a function pointer? For example:

int f(int, char**) {
    return 0;
}

int (*main)(int, char**) = &f;

This code compiles and links correctly, but triggers a segmentation fault when it's run. I believe that may be because it's trying to execute the value of the function pointer as code.

Additionally, if it's not possible in plain C++, then can it be achieved by non-standard features of gcc (maybe somehow changing the type of the exported symbol).

Finally, if it can't be achieved with gcc directives, can it be done with a custom linker script?

jleahy
  • 16,149
  • 6
  • 47
  • 66
  • 2
    Why do you need such modification for? Maybe the problem may be solved with less effort? – Spook Jan 17 '13 at 12:36
  • It's not entirely practical, it's mostly out of interest. The application I have in mind involves templates. – jleahy Jan 17 '13 at 12:39
  • 4
    Why did you tag this with both `C` and `C++` and never ask about `C` in the actual question? And why do you mess with function pointers? And why do you hate `main`? *Why?!* – stefan Jan 17 '13 at 12:49
  • This question should probably be split into two parts. One about C++ (which has been answered), and one platform-specific one about achieving the particular trickery you're after. – Kerrek SB Feb 28 '13 at 22:48

8 Answers8

6

Paragraph 3.6.1/1 of the C++ Standard says:

"A program shall contain a global function called main, which is the designated start of the program"

This makes the pointer declaration illegal.

Andy Prowl
  • 124,023
  • 23
  • 387
  • 451
4

I believe what you try to do is not possible in c++. Easiest solution I can think of is to simply call f in your main:

int f(int, char**) {
    return 0;
}

int main(int argc, char** argv) {
  return f(argc, argv);
}

I also can't imagine a scenario where the above solution will not do.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
4

I can't imagine why you would want this, but no, it's definitely not possible with plain C++.

If you really need something like this, just use a function pointer that you call as the first command in main.

zennehoy
  • 6,405
  • 28
  • 55
2

With GCC you can pass options to the linker with the -Wl option. Then you can use the --entry option of the linker to specify which function should be called first.

WARNING: This will not do what you expect! The entry function of a program is actually not the main function, but another function which sets up the run-time environment and then call your main function.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

If you are on linux, & using gcc, you can declare main as an alias to any other function.

e.g., below code works (with gcc at least, not tested with g++):

int f(int argc, char* argv[]) {
    printf("hello world\n");
    return 0;
}

int main(int argc, char* argv[]) __attribute__ ((alias("f")));
anishsane
  • 20,270
  • 5
  • 40
  • 73
0

main is a keyword in C as well as in C++ and gets overwritten as the function pointer name in your program. main defines the entry point of execution. Hence your program does not have that function and overwrites main it segfaults.

Bort
  • 2,423
  • 14
  • 22
  • 11
    No, main is not a keyword. Standard's paragraph 3.6.1.3 says the name `main` can be used elsewhere. – jrok Jan 17 '13 at 12:41
  • @jrok, ok main is not a keyword. I looked up the keyword section. Bit this seems a bit odd. How would one define another function as "main function" to be the entry point of the program than? – Bort Jan 17 '13 at 14:22
  • nvm I found this [answer](http://stackoverflow.com/questions/9677337/how-to-make-other-function-as-entry-point-other-than-main-in-c) about it. – Bort Jan 17 '13 at 14:41
0

Another "dirty" way is to create a fake function using assembly & as the first instruction of that function, jump to f.

Below is a gcc specific code for intel target:

asm(".globl main");           // main is not static
asm(".type main, @function"); // main is a 'function'
asm("main: jmp f");           // main starts here. jump to `f`

int g(){ //Some random function may be present in between "main" & "f"...
    puts("hello universe");
}

int f(int argc, char* argv[]) {
    int i;
    puts("hello world");
    printf("%d arguments given\n",argc - 1);
    for(i=0;i<argc;i++) puts (argv[i]);
    g();
    return 0;
}
anishsane
  • 20,270
  • 5
  • 40
  • 73
  • I'd have thought that just adding int main(int argc, char **argv) { return f(); } would compile down to the same thing due to the jump threading optimization. – jleahy Jan 17 '13 at 14:09
  • umm.. that's same as answer by Ivaylo. Approach in this answer is explicit jump; in case optimization is not enabled. We can however, confirm after checking assembly... :-) – anishsane Jan 17 '13 at 14:21
0

int (*main)(int, char**) = &f;

doesn't look correct.

What about

int (*main)(int, char**) = f;

?

Frank
  • 1
  • 2