The C++ Standard indicates that the main
can have two possible signatures.
int main() // (1)
int main(int, char*[]) // (2)
Moreover, main()
is typically called from __libc_start_main
, which is defined in csu/libc-start.c
in the glibc source code. The invocation of main
inside this function is copied below.
result = main (argc, argv, __environ MAIN_AUXVEC_PARAM);
We observe that the call here uses three arguments, and this appears to not produce any linker errors, despite the fact that the signature does not match either of the above two forms.
I am writing a threading library which defines main()
, and would like the application to be able to define one of the following two functions.
int AppMain() // (1)
int AppMain(int, char*[]) // (2)
Unfortunately, if I declare AppMain
using the second form above and invoke it from my library's main
, and the application uses the first form instead, then I get a unresolved reference linker error indicating that the function I invoked does not exist.
Since this does not seem to be a problem for glibc
with respect to main
, how might I write my invocation or declaration in a way that avoids the linker error?
Here is an easy way to reproduce the problem.
Makefile
CCFLAGS=-Wall -Werror
all: libLib.a App
libLib.a: Lib.o
ar rcs $@ $^
App: App.o libLib.a
g++ -o $@ $< -L. -lLib
%.o: %.cc
g++ $(CCFLAGS) -O3 $(LIBS) -fPIC -c -o $@ $<
Lib.cc
#include <stdio.h>
int AppMain(int argc, char** argv);
#undef main
int main(int argc, char** argv){
printf("Hello World\n");
AppMain(argc, argv);
}
App.cc (Working Version)
#include <stdio.h>
int AppMain(int argc, char** argv){
printf("Application says Hello world\n");
return 0;
}
App.cc (Non-Working Version)
#include <stdio.h>
int AppMain(){
printf("Application says Hello world\n");
return 0;
}
Under the second version, here is the linker error.
./libLib.a(Lib.o): In function `main':
Lib.cc:(.text.startup+0x24): undefined reference to `AppMain(int, char**)'
collect2: error: ld returned 1 exit status
Makefile:9: recipe for target 'App' failed
make: *** [App] Error 1
Regardless of suggestions to do it differently, I just answer your question
You may write your definition in
App.cc
asand your declaration in
Lib.cc
asto avoid that name mangling, the same as it's most probably done in
glibc
. There may be C++ compilers where this doesn't work, but it certainly works with the GCC.