Who calls the main function in C [duplicate] - c

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
In C, how is the main() method initially called?
I want to know, who calls the main function in C.
What is actual use of the main function ( why main is special/necessary ) ?
Can I write a c program with out main function ?

The main function is called, in practice, by the C runtime.
You can write a program without main but it must have an entry point. Different operating systems allow you to specify different entry points for your program, but they all serve the same purpose as main. On Windows, you can use WinMain. On Linux you can link without the CRT and define your own _start function (but it cannot return!)
A program without an entry point is like a car without wheels: it doesn't go anywhere.

When you ask your operating system to run a file, it loads it into memory, and jumps to it starting point (_start,etc). At this point, there is an code, that call main and then exit (The linker is responsible to this part). If you will write program without main function, the linker will give you an error, since it couldn't find it.

Your program (which is series of code bundled inside functions) must have to have a starting point right?
Something must be called first to run the rest.
So, that starting point is main, which is called by the parent process in your O/S (what ever that is) and lets your program run

Simplest answer is this: the user of your program calls the main function when they start your application. Have you ever used a command terminal? If you have you will know that you can pass arguments to a command. For example:
$ grep word myfile
What is going on under the covers is the Terminal looks at what you typed then calls the main method of the grep program and passes [word, myfile] as the second argument to this method. This is a simplification but I hope it helps.

Related

When I debug a C program with gdb, and key in 'p system', what exactly do I get?

Before I go deep into my questions, I need to confess that I am still fairly inexperienced to this subject, and am confused over quite a number of concepts, so please bear with me if my manner of asking those questions seems unorganized.
I recently learnt that as standard C library would be loaded into every C program we compiled (is this because we have #include at the beginning of the source file?[quesiton1]), we would have its functions loaded into the memory. So, I would know that the system() function had already been loaded and stored somewhere in the memory, and then I was made know that I could find the exact address of where the system() function was stored by debugging a random C program with gdb, and issuing the command 'p system', which would print out the address of the function. I understand that 'p' is used to print variable in gdb, and 'system' in this case probably indicates the address of the system() function, so it seems to make sense to do so, but then I think to myself, wait a second, it does not appear that I have used the system() function anywhere in my code, why would the inventor of gdb include such a variable for me to print out the address of some function that I don't even use? and does this imply that the address of every function in stand C library can be found out in the same fashion? and they all have a corresponding variable name in gdb? [question2]
One more question unrelated to stuff I talked above is whether functions like system(), execve() and many others are specific to Linux OS, or they are also used in Windows OS? [question3]
Hope that you guys can help me out. Thanks in advance!
The standard C library is linked with every program because it's necessary for it to be there to be able to run your program. There's a lot of things happening in your program before your main function gets called and after it returns, the standard library takes care of this. It also provides you with most of the standard functions you can call. You can compile things without a standard library, but that's an advanced topic. This is pretty much unrelated to #include.
Gdb can see system with p because it prints more than just variables. It prints anything that is in scope. system just happens to be a symbol that's visible to you in that scope. You could print any symbol that's visible to you, including all the globally visible variables and functions in libc and your program. Symbols in this context means "names of various things that need to be findable by programs and other libraries", this includes all functions, variables, section boundaries and many other things that the compiler/linker/runtime/debugger need to find to do its job.
Usually the standard library gets linked dynamically, which means that every program has the exact same copy of the library. In that case all symbols in it will be visible to your program because there's no reason to exclude them. If you link your program statically only the necessary parts of libc will be included and you would probably not see the system symbol unless you actually use that function.

What does the main() function mean for a program

What is so special about main() function in C?
In my embedded C compiler it tells the program counter where to start from. Whatever appear first (as instruction) into main function it will be placed first in the flash memory. So what about PC programs? What is the meaning of main() when we program for PC?
On a hosted implementation (basically, anything with an operating system), main is defined to be the entry point of the program. It's the function that will be called by the runtime environment when the program is launched.
On a freestanding implementation (embedded systems, PLCs, etc.), the entry point is whatever the implementation says it is. That could be main, or it could be something else.
In simple terms:
There is nothing special about the the main function apart from the fact that it is called by the system when your program is started.
The main function is where the "C program" starts, as far as the C standard is concerned. But in the real world outside the standard, where there is hardware, other things need to be done before main() is called.
On a typical embedded system, you have a reset interrupt service routine, where you end up after power-on-reset (or other reset reasons). From this ISR, the following should be done, in this order:
Set the stack pointer.
Set all other memory mapping-related things (MMU registers)
Safety features like watchdog and low voltage detect are initialized.
All static storage duration variables are initialized.
main() is called.
So when main() is called, you have a stable enough environment for standard C programs to execute as expected.
To use main() as the reset vector is unorthodox and non-standard. The C standard requires that static storage duration variables are already initialized before main() is called. Also, you really don't want to do fundamental things like setting the stack pointer inside main(), because that would mess up all local variables you have in main().
When your OS runs a program your program needs to pass control over to it. And the OS only knows where to begin inside of your program at the main() function.
Have you searched on the internet? Take a look in here, and also here.
When the operating system runs a program in C, it passes control of
the computer over to that program ... the key point is that the operating system needs to know where
inside your program the control needs to be passed. In the case of a C
language program, it's the main() function that the operating system
is looking for.
Function main is special - your program begins executing at the beginning of
main. This means that every program must have a main somewhere.
main will usually call other functions to help perform its job, some that you wrote, and others
from libraries that are provided for you.
You find it in every possible C book.
The main function allows the C program to find the beginning of the program. The main function is always called when the program is started.

What function actually calls WinMain

How is WinMain() actually called? I remember a function used by pro-hackers that started with (something) that looked like __startupWinMain().
The problem is, I have a Win32 EXE(compiled with /SUBSYSTEM:WINDOWS) but gets arguments from command-line. If the command line is incorrect, the process should print a help message to the console.
How can I manually deallocate(or FreeConsole()) from an exe with /SUBSYSTEM:WINDOWS linker option?
As the very first act of your program, check the parameters. If they are fine, continue as normal.
Otherwise call AttachConsole passing ATTACH_PARENT_PROCESS. If that succeeds, then you can print your error to stdout and quit. If it doesn't, then you'll have to show the error in a message box.
Perhaps you should consider having the program pop up a message box when the command line is incorrect. Something like this:
MessageBox( NULL, "(description of command line error)",
"MyProg - Command Line Error",
MB_OK|MB_ICONEXCLAMATION );
This will open a message box in the center of the display and wait for the user to acknowledge it before actually terminating your program.
On the other hand, you could build your program as a console app and use printf() to write to the console. A console program may still create windows, but the console itself will hang around unless you figure out how to detach from it (and then, of course, you will no longer be able to use printf().)
How does the compiler know to invoke wWinMain instead of the standard main function? What actually happens is that the Microsoft C runtime library (CRT) provides an implementation of main that calls either WinMain or wWinMain.
Note The CRT does some additional work inside main. For example, any static initializers are called before wWinMain. Although you can tell the linker to use a different entry-point function, use the default if you link to the CRT. Otherwise, the CRT initialization code will be skipped, with unpredictable results. (For example, global objects will not be initialized correctly.)
How is WinMain() actually called?
If you single-step to the first line of your program in a debugger, and then look at the stack, you can see how WinMain gets called. The actual start function for a typical build is a function pulled in from the run-time library. For me, it's _WinMainCRTStartup, but I suppose it might vary depending on the version of the compiler, linker, and library you build with. The startup function from the run-time library does some initialization and then calls WinMain.
Using dumpbin /headers (or another program that can inspect a PE binary), you can confirm which function is the "entry point" to your executable. Unless you've done something to change it, you'll probably see _WinMainCRTStartup, which is consistent with what the stack trace tells us.
That should answer your question, but it doesn't solve your problem. It looks like some others have posted good solutions.

What is the need for C startup routine?

Quoting from one of the unix programming books,
When a C program is executed by the
kernelby, one of the exec functions
calls special start-up routine. This
function is called before the main
function is called. The executable
program file specifies this routine as
the starting address for the program;
this is set up by the link editor when
it is invoked by the C compiler. This
start-up routine takes values from the
kernel the command-line arguments and
the environment and sets things up so
that the main function is called as
shown earlier.
Why do we a need a middle man start-up routine. The exec function could have straightway called the main function and the kernel could have directly passed the command line arguments and environment to the main function. Why do we need the start-up routine in between?
Because C has no concept of "plug in". So if you want to use, say, malloc() someone has to initialize the necessary data structures. The C programmers were lazy and didn't want to have to write code like this all the time:
main() {
initialize_malloc();
initialize_stdio();
initialize_...();
initialize_...();
initialize_...();
initialize_...();
initialize_...();
... oh wow, can we start already? ...
}
So the C compiler figures out what needs to be done, generates the necessary code and sets up everything so you can start with your code right away.
The start-up routine initializes the CRT (i.e. creates the CRT heap so that malloc/free work, initializes standard I/O streams, etc.); in case of C++ it also calls the globals' constructors. There may be other system-specific setup, you should check the sources of your run-time library for more details.
Calling main() is a C thing, while calling _start() is a kernel thing, indicated by the entry point in the binary format header. (for clarity: the kernel doesn't want or need to know that we call it _start)
If you would have a non-C binary, you might not have a main() function, you might not even have the concept of a "function" at all.
So the actual question would be: why doesn't a compiler give the address of main() as a starting point? That's because typical libc implementations want to do some initializations before really starting the program, see the other answers for that.
edit as an example, you can change the entry point like this:
$ cat entrypoint.c
int blabla() { printf("Yes it works!\n"); exit(0); }
int main() { printf("not called\n"); }
$ gcc entrypoint.c -e blabla
$ ./a.out
Yes it works!
Important to know also is that an application program is executed in user mode, and any system calls out, set the privileged bit and go into kernel mode. This helps increase OS security by preventing the user from accessing kernel level system calls and a myriad of other complications. So a call to printf will trap, set kernel mode bit, execute code, then reset to user mode and return to your application.
The CRT is required to help you and allow you to use the languages you want in Windows and Linux. it provides some very fundamental bootstrapping into the OS to provide you with feature sets for development.

Some general C questions

I am trying to fully understand the process pro writing code in some language to execution by OS. In my case, the language would be C and the OS would be Windows. So far, I read many different articles, but I am not sure, whether I understand the process right, and I would like to ask you if you know some good articles on some subjects I couldnĀ“t find.
So, what I think I know about C (and basically other languages):
C compiler itself handles only data types, basic math operations, pointers operations, and work with functions. By work with functions I mean how to pass argument to it, and how to get output from function. During compilation, function call is replaced by passing arguments to stack, and than if function is not inline, its call is replaced by some symbol for linker. Linker than find the function definition, and replace the symbol to jump adress to that function (and of course than jump back to program).
If the above is generally true and I get it right, where to final .exe file actually linker saves the functions? After the main() function? And what creates the .exe header? Compiler or Linker?
Now, additional capabilities of C, today known as C standart library is set of functions and the declarations of them, that other programmers wrote to extend and simplify use of C language. But these functions like printf() were (or could be?) written in different language, or assembler. And there comes my next question, can be, for example printf() function be written in pure C without use of assembler?
I know this is quite big question, but I just mostly want to know, wheather I am right or not. And trust me, I read a lots of articles on the web, and I would not ask you, If I could find these infromation together on one place, in one article. Insted I must piece by piece gather informations, so I am not sure if I am right. Thanks.
I think that you're exposed to some information that is less relevant as a beginning C programmer and that might be confusing you - part of the goal of using a higher level language like this is to not have to initially think about how this process works. Over time, however, it is important to understand the process. I think you generally have the right understanding of it.
The C compiler merely takes C code and generates object files that contain machine language. Most of the object file is taken by the content of the functions. A simple function call in C, for example, would be represented in the compiled form as low level operators to push things into the stack, change the instruction pointer, etc.
The C library and any other libraries you would use are already available in this compiled form.
The linker is the thing that combines all the relevant object files, resolves all the dependencies (e.g., one object file calling a function in the standard library), and then creates the executable.
As for the language libraries are written in: Think of every function as a black box. As long as the black box has a standard interface (the C calling convention; that is, it takes arguments in a certain way, returns values in a certain way, etc.), how it is written internally doesn't matter. Most typically, the functions would be written in C or directly in assembly. By the time they make it into an object file (or as a compiled library), it doesn't really matter how they were initially created, what matters is that they are now in the compiled machine form.
The format of an executable depends on the operating system, but much of the body of the executable in windows is very similar to that of the object files. Imagine as if someone merged together all the object files and then added some glue. The glue does loading related stuff and then invokes the main(). When I was a kid, for example, people got a kick out of "changing the glue" to add another function before the main() that would display a splash screen with their name.
One thing to note, though is that regardless of the language you use, eventually you have to make use of operating system services. For example, to display stuff on the screen, to manage processes, etc. Most operating systems have an API that is also callable in a similar way, but its contents are not included in your EXE. For example, when you run your browser, it is an executable, but at some point there is a call to the Windows API to create a window or to load a font. If this was part of your EXE, your EXE would be huge. So even in your executable, there are "missing references". Usually, these are addressed at load time or run time, depending on the operating system.
I am a new user and this system does not allow me to post more than one link. To get around that restriction, I have posted some idea at my blog http://zhinkaas.blogspot.com/2010/04/how-does-c-program-work.html. It took me some time to get all links, but in totality, those should get you started.
The compiler is responsible for translating all your functions written in C into assembly, which it saves in the object file (DLL or EXE, for example). So, if you write a .c file that has a main function and a few other function, the compiler will translate all of those into assembly and save them together in the EXE file. Then, when you run the file, the loader (which is part of the OS) knows to start running the main function first. Otherwise, the main function is just like any other function for the compiler.
The linker is responsible for resolving any references between functions and variables in one object file with the references in other files. For example, if you call printf(), since you do not define the function printf() yourself, the linker is responsible for making sure that the call to printf() goes to the right system library where printf() is defined. This is done at compile-time.
printf() is indeed be written in pure C. What it does is call a system call in the OS which knows how to actually send characters to the standard output (like a window terminal). When you call printf() in your program, at compile time, the linker is responsible for linking your call to the printf() function in the standard C libraries. When the function is passed at run-time, printf() formats the arguments properly and then calls the appropriate OS system call to actually display the characters.

Resources