So from what I've been taught, in school and in books, all C programs(I assume C++ too) always have main(). That's very explicitly mentioned. However in my poking around with some relatively large open source projects in hopes of learning something, it isn't as straight forward.

What I've encountered was that there were a lot of C files that only contained function definitions, as if being used as header files(which was confusing too since they weren't called via include. How they kind of go together escapes me). I found it weird because it seems that they were all connected, really contrary to what I know.

Bottom line I couldn't find main, intelligently looking at the C files that would probably contain it. I asked someone and he said the IDE kind of works it out which was confusing for me since where is the flow, where do the functions get called/invoked.

WHERE IS MAIN! :'(

If it means anything the projects were eAthena and mpc. Although just to lay it out I don't know anything about C++, which is what mpc is written on.

Recommended Answers

All 11 Replies

all C programs(I assume C++ too) always have main().

All C programs have an entry point, and the standard entry point is called main().

I found it weird because it seems that they were all connected, really contrary to what I know.

There are essentially two steps for building an executable: compilation and linking. To compile a source file, you don't need definitions, only declarations. That's why this is perfectly legal and will compile without complaint:

#include <stdio.h>

extern int foo; /* Declaration for user-defined variable */

int add(int a, int b); /* Declaration for user-defined function */

int main(void)
{
    foo = 2 + 3;
    printf("%d\n", foo);
    return 0;
}

If you try to link it into an executable, the linker will complain that foo and add() don't exist. However, if you add another source file with the definitions:

int foo = 0;

int add(int a, int b)
{
    return a + b;
}

compile it, and link the two together, everything works peachy through the magic of linking. Large projects in C will consist of *.h and *.c file pairs where the *.h file contains declarations and the *.c file contains corresponding definitions. The *.h files are included wherever the declarations are needed, and the *.c files are all linked together.

Bottom line I couldn't find main, intelligently looking at the C files that would probably contain it.

You may be looking at a project that uses a different entry point to conform with a graphics API. Win32 API programs, for example, often replace main() with WinMain() because it's a more convenient entry point for windowed GUIs.

When you run a program you ask it to execute the main() function. everything else in c files used to support what inside the main function. consider following examples.

int main()
{
	int x;
	x = 5;

	return 0;
}

this will work. it doesn't need any header files to be included since we don't use any library functions such as printf() and also no user defined functions are used.

int add(int a, int b)
{
	return a+b;
}

this won't work since it doesn't have a main function. my compiler gives me following error messages.

/usr/lib/x86_64-linux-gnu/gcc/x86_64-linux-gnu/4.5.2/../../../crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: ld returned 1 exit status

about the header files....

header files are created to be reusable. so, you can just #include <header_file> without rewriting the code. so, it contains only functions that make sense.

What I've encountered was that there were a lot of C files that only contained function definitions, as if being used as header files(which was confusing too since they weren't called via include. How they kind of go together escapes me). I found it weird because it seems that they were all connected, really contrary to what I know.

if we #include <header1.h> in header2.h and #include <header2.h> in our program code, it is not necessary to include header1.h again.

I asked someone and he said the IDE kind of works it out which was confusing for me since where is the flow, where do the functions get called/invoked.

yes. that's why i'm not a big fan of IDEs. IDE figures out the files to be compiled and how they should be compiled and linked. for starter, don't use IDE or you'll never find the answer to these questions.

I think you should read a little bit about compiling a program with multiple source files. then you would understand this.

Oh now that you mention 'entry point', I found something that resembles main() name do_init(). The projects all have this in common so I'll assume this is the entry point. Is it possible to rename the entry point?

Also regarding source files:

#include "fiction.h" //wherein this contains ONLY declarations

int main(){
 fiction_func();
 return 0;
}

This would produce an error wherein it would look for the definition, no? Now if I would simply create a .c file wherein it would contain the definition, I would be good? The linker would automatically find it for me? Does it have to be named the same as the header? or not necessarily?

This can be done in three different ways.

1. you can implement fiction_func() inside the fiction.h

fiction.h

void fiction_func()
{
/* your code */
}

2. write a separate c file implementing the function

fiction.c

void fiction_func()
{
/* your code */
}

3. create fiction.h where we declare the function prototype. and fiction.c which has the real implementation of fiction_func()

fiction.h

void fiction_func();

fiction.c

void fiction_func()
{
/* your code */
}

but in the last case you have to compile the fiction.c first and then link it.

Actually, you know what do_init() is not the entry point at all. Now I'm completely lost again. :<

To get some of the theory behind this, see here. That discusses the role of linkers and inclusion headers, and how they are used in C and it's relatives. This may help put what Narue said into perspective. While what I wrote then focuses on reusable code libraries, the principles also apply to being able to break programs up into multiple files for the sake of modularity and clarity.

The key thing to understand is that yes, there is a main() function somewhere (or some equivalent to it, such as winMain() , depending on the environment in use), but not all of the compiled sections need to have there own main() in the file itself. When you compile a file, you only produce a part of the program; the rest of it has to be linked in before the final executable is completed. Most Integrated Development Environments take care of this for you to some extent, so you simply weren't aware of it before.

As gihanbw said, using an IDE tends to hide a lot of details which you really need to be at least aware of, if not necessarily actively using. You would learn the process a lot more clearly if you were to try compiling a few small programs (e.g., the one Narue posted) with the command line versions of your compiler and linker, just to see how the process works 'under the hood' as it were.

Yes I know now that not all C files necessarily have to have main(). However... I've opened the C files within the project that made sense and there wasn't any main. I thought I found it based from the definition which had argc and argv as parameters but when I tested it it seems that it was just being invoked by yet another function. There is no loop which means it should just terminate.

http://eathena-project.googlecode.com/svn/trunk/src/char/ is the particular one I'm poking with just to figure things out. char.c is the likely one to contain main with respect to the final exe file name.

do_init is the very last function. The exe file doesn't terminate as what do_init's logic would imply. Unless I read that completely wrong. This is killing me.

Check out http://eathena-project.googlecode.com/svn/trunk/src/common/core.c. Also notice how core.o is get linked (http://eathena-project.googlecode.com/svn/trunk/src/char/Makefile.in):

COMMON_OBJ = ../common/obj_all/core.o (and a bunch more common objects)
...
char-server: obj_txt $(CHAR_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ)
	@CC@ @LDFLAGS@ -o ../../char-server@EXEEXT@ $(CHAR_OBJ) $(COMMON_OBJ) $(MT19937AR_OBJ) @LIBS@

I found main in core.c. :< Thanks for that. I swear I checked that one already. Maybe I was just put off by the logo-print function.

Also is there any way to find the 'main C file' by looking at a particular 'compile file'? and if so which?

Build a complete application with for debugging. Load it into a debugger. If it is gdb, type b main at the prompt, and then run . Once gdb hits the breakpoint, it will display source file and line number. Adjust for other debuggers accordingly.

Also, you can use the nm executable on an object file (or an executable) and it will give you a list of functions. If main is in there, you'll see it.

This does of course require you to be using an OS that comes with nm, or has nm or a similar programme available.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.