[Courses] C Programming For Absolute Beginners, Lesson 5: All About Functions, part 1

Christopher Howard christopher.howard at frigidcode.com
Wed Mar 14 03:15:02 UTC 2012


On 03/13/2012 05:57 PM, Sachin Divekar wrote:
>>
>> code:
>> ----------
>> // file main.c
>>
>> int myadd (int, int);
>>
>> int main ()
>> {
>>  return myadd (3, 2);
>> }
>>
>> // file add.c
>> int myadd (int a, int b)
>> {
>>  return a + b;
>> }
>>
>> // You would then compile and link the two files together with this command:
>>
>> gcc main.c add.c -o myprogname
> 
> 
> What is the difference between using #include and linking together
> using gcc as shown in above example?
> 

As far as the compiler is concerned, there is no difference. A file that
is included into a file is just inserted into it by the C preprocessor.
If we wrote the above program using a header file, it would look like so:

code:
----------
// file main.c

#include "add.h"

int main ()
{
  return myadd (3, 2);
}

// file add.h

int myadd (int, int);

// file add.c

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

// You would then compile and link the two (non-header) files together
with this (same) command:

gcc main.c add.c -o myprogname
----------

Either approach has the same result. Practically though, it can often be
more convenient to put the prototype in a separate header file. In the
above example it is not obvious. But suppose that add.c had 30 different
functions in it, and that you needed to use those functions in 12
different source code files. Well, if you put all the prototypes in one
header file ("add.h") then you would simply need to put "#include
"add.h"" at the top of each source file. Otherwise, you would have to
personally copy 30 prototypes into each of the source files.
Furthermore, you would have to edit each single file if one of those
prototypes changed, which would be a real pain.

> 
>> ----------
>>
>> Though, as I said, it is usually more sensible to put the prototype in a
>> separate file and #include it among the various files that need it. With
>> shared libraries (utilizing dynamic linking), you also #include a
>> prototype from a header, but the real function is not provided at all
>> during compiling! Rather, it is provided later by the system at the
>> beginning of the program's execution. This allows people to code their
>> programs for a particular library interface (i.e., set of function
>> prototypes) while the library functions themselves may differ somewhat
>> from system to system. (For example, depending on the special needs of
>> the system. This is how OpenGL still works, even though we all have
>> different graphics cards.)
>>
> 
> Can somebody please elaborate this paragraph?
> 

For example, when you want to use the printf() function to print stuff
out, you have to put the "#include <stdio.h>" statement at the top of
your source code file. All that does is copy the function prototypes
from /usr/include/stdio.h into your source code.

When you compile your program, the resulting binary does not actually
have the function "printf()" stored inside of it. It simply has a
reference to said function name. When you execute the binary, your
program loads up the libc library provided by your system (usually
located at /usr/lib/libc.so) and uses the printf() function inside of it.

If you send your program off to a buddy, and he executes it, the program
will do the same thing: load the library and use printf(). However, if
his system is older than yours, or configured differently, his version
of printf() might look different and work different on the inside (even
though it produces the same result - printing stuff).

Likewise, all of us can write programs with accelerated 3D graphics the
same way, using the OpenGL library (prototypes), even though we all have
different graphics cards and our systems process graphics differently.
When you write a program, you just "#include <GL/gl.h>" at the top of
the file (or something like that). Then each system that wants to use
the program simply needs to provide a GL library for the program to
load. On my system, it is at /usr/lib64/libGL.so, which is actual a
shortcut (soft link) to /usr/lib64/opengl/xorg-x11/lib/libGL.so.1.2.
This library can be implemented differently on every system, so long as
it provides the needed functions.

I likely oversimplified a few things, but I hope that helps.

-- 
frigidcode.com
indicium.us



More information about the Courses mailing list