header files

A

ambika

Iam just trying to know "c".
And I have a small doubt about these header files.
The header files just contain the declaration part...Where is the
definition for these declarations written??And how does that get
linked to our program when we run it??I would appreciate any helpful
info..And I would like to thank you for that in advance
-ambika
 
B

Barry Margolin

Your question is not about the C /language/, which is what comp.lang.c is
about, or the C /standard/, which is what comp.std.c is about. It is
therefore off-topic in both groups. Please ask in a newsgroup dedicated to
(software development on) your system.

I interpreted his question as generic curiosity, not specific to any
particular system. What's the group dedicated to "how computer systems
typically work"?
 
M

Martin Dickopp

Barry Margolin said:
I interpreted his question as generic curiosity, not specific to any
particular system.

So did I. But the answer is different for different systems, therefore an
answer which is not specific to any particular system is impossible.
What's the group dedicated to "how computer systems typically work"?

It depends on the system. If the system is a variant of Unix,
comp.unix.programmer will likely answer the OP's question. Is the system is
Microsoft Windows, it is highly likely that a group dedicated to software
development on that platform exits, but I cannnot recommend any as I don't
have any experience or knowledge in that field (haven't used a Microsoft
product in the last ten years).

Of course, if the OP uses something obscure like a C interpreter on a cell
phone, it might in fact be the case that no newsgroup for that system
exists...

Martin
 
F

Francis Glassborow

ambika said:
Iam just trying to know "c".
And I have a small doubt about these header files.
The header files just contain the declaration part...Where is the
definition for these declarations written??And how does that get
linked to our program when we run it??I would appreciate any helpful
info..And I would like to thank you for that in advance

They are provided by implementation files, object files or libraries
which the linker accesses to create the executable.
 
D

Douglas A. Gwyn

ambika said:
The header files just contain the declaration part...Where is the
definition for these declarations written??And how does that get
linked to our program when we run it??

Usually the definitions for the external functions and
objects are contained in one or more "object libraries"
which must be linked with the object modules produced
by compiling your program's source code. The standard
headers correspond to the system's standard C library,
which is usually linked with your program by default,
so that you may be unaware of it. Other libraries are
provided by, and spcific to, the development platform
or a third-party support-software provider. You can
create your own libraries of reusable functions, too.
 
A

ambika

Thanks to all of you
..
But I have a small question.I tried to save a program in C with the
".h"extention.I did not include the header files.I just wrote a few
functions.Then i included the file as what we do include our header
files.It just worked fine.Here I have both declared and defined the
functions.
But when I saved the same program with ".C" extention and include that
file in the program it also works the same way...
Have the really succeeded in saving my program as a header file in
the first case???
Am asking this because both the defn and declaration is done there
itself..and no linking is required in this case and that does not make
any diff b/w my ".h" and ".c" files when included.
 
B

Barry Margolin

Thanks to all of you
.
But I have a small question.I tried to save a program in C with the
".h"extention.I did not include the header files.I just wrote a few
functions.Then i included the file as what we do include our header
files.It just worked fine.Here I have both declared and defined the
functions.
But when I saved the same program with ".C" extention and include that
file in the program it also works the same way...
Have the really succeeded in saving my program as a header file in
the first case???
Am asking this because both the defn and declaration is done there
itself..and no linking is required in this case and that does not make
any diff b/w my ".h" and ".c" files when included.

The #include directive doesn't care whether you name the file .C or .h or
anything else. The file named in the directive is simply treated as if it
were in the file that contains that line (there are some small differences,
but they're not relevant to your question).

The normal procedure of putting declarations in .h files and definitions in
..c files is a software engineering convention, not something dictated by
the language. It's useful when different parts of an application are
developed by different organizations.

For instance, since commercial OS and library vendors often don't want to
supply source code of their programs, you can't use the technique of
including the source file. They provide a binary library and a header file
that contains only the declarations of their functions.
 
J

James Kuyper

Barry said:
The #include directive doesn't care whether you name the file .C or .h or
anything else. The file named in the directive is simply treated as if it
were in the file that contains that line (there are some small differences,
but they're not relevant to your question).

That's correct, but are a great many tools out there which assume that a
*.c file is C source code, and that a *.h file is a C header file.
Violating that convention is certainly legal, but may prove
inconvenient.
 
J

John Bode

Thanks to all of you
.
But I have a small question.I tried to save a program in C with the
".h"extention.I did not include the header files.I just wrote a few
functions.Then i included the file as what we do include our header
files.It just worked fine.Here I have both declared and defined the
functions.
But when I saved the same program with ".C" extention and include that
file in the program it also works the same way...
Have the really succeeded in saving my program as a header file in
the first case???
Am asking this because both the defn and declaration is done there
itself..and no linking is required in this case and that does not make
any diff b/w my ".h" and ".c" files when included.

The whole matter of using .h to mark a file as a header file and .c to
mark a file as a source file is a matter of convention, not a
requirement of the C language itself. As far as the C language is
concerned, you can include a .h file, or a .c file, or anything else,
as long as the contents of that file are legal C code. You don't even
have to #include any files at all if you aren't using any functions
defined outside of your particular program.

It is true that many development tools make the distinction between .h
and .c files, but that's because the convention has become so common
over the years. Also, not all platforms even allow you to name a file
so that it has a .h or .c extension. HP's MPE file system uses the
naming convention file.account.user, so if I created a header file
containing types and prototypes for a networking module, the include
directive would look something like

#include "netdfs.dev.jbode"

The standard library headers (stdio.h, stdlib.h, math.h, etc.) are
treated as special cases, so that you can use

#include <stdio.h>

on any system, including systems like MPE where stdio.h is not a legal
filename, and the right file contents will be loaded.

It is the generally accepted practice that #include files only contain
macro definitions, type definitions, and function prototypes. In
other words, these files define the *interface* to a module or
library, with the implementation of that module or library appearing
in separate source files. The primary reasons for doing this are that
it makes large projects easier to manage, and permits the same code to
be used easily in multiple projects. You break the project down into
a number of modules, implement each module in one or more source
files, compile each module into separate object files or libraries,
and define an interface to each module so other modules may use it.
Each module can be compiled and tested separately, and changes made to
any one module will have little or no effect on other modules if no
changes to the interface are necessary. If you write a
general-purpose module, it can be linked into a number of projects
(just as almost every C program uses printf() or fopen()).

There's no language requirement saying you *can't* put function
definitions in an included file, but there are several good reasons
for not doing so. First of all, function names are exported to the
linker unless you declare them as "static", so if you link two files
together that include the same function definition, you may get a
linker error.

For example, say you have the following files:

/* foo.h */
int foo (void)
{
return 1;
}

/* bar.c */
#include <stdio.h>
#include "foo.h"

int bar (void)
{
int x = foo();
return x;
}

/* main.c */
#include <stdio.h>
#include "foo.h"

int main (void)
{
extern int bar (void);
printf ("bar() returns %d\n", bar());
printf ("foo() returns %d\n", foo());
return 0;
}

Here's what happens when I try to build this in Cygwin using gcc:

jbode@JBODE-2K ~/cstuff/badpractice
$ gcc -o bad main.c bar.c
/cygdrive/c/WINDOWS/TEMP/ccYJ0xkP.o(.text+0x0):bar.c: multiple
definition of `foo'
/cygdrive/c/WINDOWS/TEMP/ccjj5LwY.o(.text+0x0):main.c: first defined
here
collect2: ld returned 1 exit status

The ld linker is complaining because the *definition* of the function
foo() appears in both main.c and bar.c. It's not smart enough to know
that the function is the same in both files, and that one of the
definitions can be safely ignored. You don't want to put global
variable definitions in included files for the same reason.

Another reason for not doing this is that the included file has to be
parsed and compiled every time it appears. So if you include a
hundred-line function in 20 different source files, that same function
has to be parsed and compiled 20 times. And if that function
definition changes, *all* the files that include it must be
recompiled.

Here's the right way to structure the example given above:

/* foo.h -- defines the interface to foo() */
#ifndef FOO_H /* These two lines prevent a file from being included*/
#define FOO_H /* more than once in the same translation unit */

extern int foo (void);

#endif

/* foo.c -- implements the function foo() */
#include "foo.h"

int foo (void)
{
return 1;
}

/* bar.h -- defines interface to bar() */
#ifndef BAR_H
#define BAR_H

extern int bar (void);

#endif

/* bar.c -- implements function bar() */
#include "bar.h"
#include "foo.h" /* remember this is the *prototype*, not the
definition */

int bar (void)
{
int x = foo();
return x;
}

/* main.c -- calls foo() and bar() functions */
#include <stdio.h>
#include "foo.h"
#include "bar.h"

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

Now, if I make any changes to foo.c, all I have to do is recompile
that one file and relink; I don't have to recompile bar.c and main.c.
 
N

Neil Cerutti

(e-mail address removed) (ambika) wrote in message


The whole matter of using .h to mark a file as a header file and .c to
mark a file as a source file is a matter of convention, not a
requirement of the C language itself.

I like to call my C source files .a and my header files .dll.
Ha HAH!
 
D

Douglas A. Gwyn

James said:
That's correct, but are a great many tools out there which assume that a
*.c file is C source code, and that a *.h file is a C header file.
Violating that convention is certainly legal, but may prove
inconvenient.

More than that, the partitioning of "modules" into separate interface
(.h) and implementation (.c) files is the result of evolution, and
reflects a well-established software engineering principle.
 
J

James Kuyper

Douglas A. Gwyn said:
More than that, the partitioning of "modules" into separate interface
(.h) and implementation (.c) files is the result of evolution, and
reflects a well-established software engineering principle.

True, but there's at least one case (admittedly a rather special one)
where I have found it very useful to violate that principle:

wrapotherfunc.c:
================================
#define otherfunc realotherfunc
#include "otherfunc.c"
#undef otherfunc
int special_case=0;

int otherfunc(int i)
{
if(i==special_case)
return -1;
return realotherfunc(i);
}
================================

This allows me to create a controllable wrapper for otherfunc() that
links with other modules just as if it were the real one, and has, in
the non-special cases, exactly the same behavior as the real version.
Most importantly, it will continue to have the same behavior even if
otherfunc.c changes, so long as wrapotherfunc.c is recompiled after the
changes. The special_case variable is an example of how the behavior of
the wrapper can be controlled by a test driver.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,077
Messages
2,570,568
Members
47,204
Latest member
abhinav72673

Latest Threads

Top