12

So I'm following along in Head First C and we're on a chapter where we learn to compile multiple files together. One of them is encrypt.c.

#include "encrypt.h" void encrypt(char *message) { char c; while (*message) { *message = *message ^ 31; message++; } } 

The encrypt.h file repeats the first line with a semicolon at the end, so why do I need it? I understand why I would need header files to fix the problem of using a function before it's defined, so I could understand #including it in a file that uses encrypt.c, but why would I need it inside encrypt.c? Is it just one of those "because" reasons?

3
  • You cannot use a function before it is defined. You can declare the header for the function and then use it after it has been defined. But a header file does not grant you superuser in that it allows you to use an undeclared function. Commented Aug 25, 2013 at 21:07
  • 3
    Not relevant in this particular example, but header files also often define typedefs and structs and all kinds of things that the functions declared in that header may want to use. Commented Aug 25, 2013 at 21:12
  • I have some others, too. This book has faults but they all do. Commented Aug 25, 2013 at 21:22

6 Answers 6

20

If the contents of encrypt.c are shown in their entirety, then you don't need the header. But it's still a good idea to include it because:

  1. If one function in the file uses another, then the order of definition matters because the callee must be defined before the caller. It's even possible to have two functions A and B where each calls the other, in which case you cannot get the code to compile without at least one forward declaration. Including the header with the forward declarations solves these problems.
  2. Consuming the header just like your client code does is a good way to have the compiler point out discrepancies between the signatures in the forward declarations and the actual function definitions. If undetected this kind of problem can lead to "interesting" behavior at runtime and lots of hair-pulling.
Sign up to request clarification or add additional context in comments.

4 Comments

I like your second point. The book brought up your first point of functions that mutually call each other, so ping calls pong and pong calls ping, and I understand how the header would solve that, but I thought, here we only have one function, is it just to get me in the habit?
@punstress: In essence it is. And it's a good habit to get into. ;-)
@Jon In essence it's a good practice to always separate interface from implementation, right?
@NlightNFotis: Sure, but that's not what this is about. Also, "always" is a strong word in practical engineering because quite often it might involve a lot of work and YAGNI.
6

You're right, if that's all encrypt.h declares, you don't need to include it in the .c file.

You mostly do it for consistency.

Comments

6

Imagine that you change encrypt.c to void encrypt(char *message, int i) { }

If you don't include encrypt.h you won't notice that the other files in your application haven't been updated to pass the new parameter. If you update encrypt.h and encrypt.c at the same time the compiler can do checking for you.

1 Comment

Was just rereading this from last year, and I like your point. Thx.
3

It's good style. Sometimes, C-file with function implementation and C-file with function usage shares common declarations - types/structures, This shares declarations places at the H-file. For ex.

[enc.h] typedef enum {S,F} Res; EN encode(); [enc.c] #include "enc.h" Res encode() { ... } [other.c] Res res; res = encode(); 

Comments

0

It is prototyping the function

http://en.wikipedia.org/wiki/Function_prototype

Comments

0

Then you include the header in a another *.c-file the compiler knows in this way that anywhere else is the function definition.

This ist like:

#include <stdio.h> int main (void) { afun(); return 0; } void afun (void) { printf("hello\n"); } 

Now the compiler doesn't know what to do with afun() in the main function. Because it was'nt defined. So it will lead into an compiler error.

So you add the declaration at the beginning or bevore the first usage:

#include <stdio.h> void afun(void); int main (void) { afun(); return 0; } void afun (void) { printf("hello\n"); } 

Know the compiler knows the deklaration of afun and hopes anythere else the function is defined. With header files it is possible to use precompiled c-code. The only thing the compiler is needed is the deklaration of the function.

2 Comments

The OP said "I understand why I would need header files to fix the problem of using a function before it's defined" right in her initial post...
Yes I would show: With header files it is possible to use precompiled c-code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.