Ahmed ZZZ
Ahmed ZZZ

Reputation: 13

Redefining main to another name

In C90, can I redefine main and give it another name, and possibly add extra parameters using #define?
Have this in a header file for example:

#include <stdio.h>
#include <stdlib.h>
#define main( void ) new_main( void )

int new_main( void );

The header doesn't show any errors when compiling. When I try compiling it with the main C file, however, I keep getting an error

In function '_start': Undefined reference to 'main'     

Upvotes: 1

Views: 234

Answers (4)

jacob
jacob

Reputation: 4956

Assuming you're using gcc passing -nostdlib to your program, and then set a new entry, by passing this to gcc which passing it to the linker, -Wl,-enew_main. Doing this won't give you access to any of the nice features that the C runtime does before calling your main, and you'd have to do it yourself.

You can look at resources about what happens before main is called.

What Happens Before main

Upvotes: 0

ChuckCottrill
ChuckCottrill

Reputation: 4444

No you cannot (as Grigory said).

You can however, immediate call your proxy main,

int
your_new_main(int argc, char* argv[], char* envp[]) {
    ... //your stuff goes here
}

//just place this in an include file, and only include in main...
int
main( int argc, char* argv[], char* envp[])
{
    int result = your_new_main(argc, argv);
    return result;
}

As far as whether envp is supported everywhere?

Upvotes: 0

supercat
supercat

Reputation: 81207

The presence of #define main new_main within a compilation unit will not affect the name of the function the implementation will call on program startup. The implementation is going to call a function called main regardless of any macros you define.

If you are going to use a #define like that to prevent the primary declaration of main() from producing a function by that name, you'll need to include a definition of main() somewhere else; that alternate version could then invoke the original. For example, if the original definition didn't use its arguments, and if the program exits only by returning from main() [as opposed to using exit()] you might put #define main new_main within a header file used by the primary definition of main, and then in another file do something like:

#include <stdio.h>
#include <conio.h>  // For getch() function.
int main(void)
{
   int result = main();
   printf("\nExit code was %d.  Strike any key.\n", result);
   getch();
   return result;
}

In most cases, it would be better to add any such code within the ordinary "main" function, but this approach can be useful in cases where the file containing main is produced by code generation tools on every build, or for some other reason cannot be modified to include such code.

Upvotes: 0

Grigory Rechistov
Grigory Rechistov

Reputation: 2214

No, you cannot do that, because it would be against language and OS standards. The name main and its arguments argc, argv and environ constitute a part of system loader calling conventions.

A bit simplifying explanation (no ABI level, just API level) ensues. When your program has been loaded into memory and is about to start, the loader needs to know which function to call as an entrypoint, and how to pass its environment to it. If it was be possible to change the name of main and/or its parameter list, it would have been needed to communicate details of new calling interface back to the loader. And there is no convenient way to do it (apart from writing your own executable loader).

In function '_start': Undefined reference to 'main'

Here you can see an implementation detail of Linux/POISX ELF loader interface. The compiler adds function _start to your program behind the scenes, which is an actual program entrypoint. _start is tasked to do extra initialization steps common to most programs that use LibC. It is _start that later calls your main. Theoretically, you could write a program that has its own function called _start and no main and it would be fine. It is not trivial as you will have to make sure that the default _start code is no longer being attached to your program (no double definitions), but it is doable. And no, you cannot choose other name than _start for the same reasons.

Upvotes: 2

Related Questions