Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why I need C header files?

It is a dumb question, I admit. Code will explain it better. Got these files:

hello.c:

#include <stdio.h>

void hello(char * s)
{
    printf("hello, %s\n", s);
}

main.c:

int main()
{
    hello("world!");
    return 0;
}

makefile:

test : main.o hello.o
    gcc -o test main.o hello.o

main.o : main.c
    gcc -c main.c

hello.o : hello.c
    gcc -c hello.c

.PHONY : clean
clean :
    -rm test
    -rm main.o
    -rm hello.o

I can just "make" and "./test" it and it works. Shouldn't I need to include something like hello.h in main.c just so the compiler knows the function prototype?

I didn't even include hello.c anywhere and it just works! How come main.c knows about the hello function?

If that works, when do I need .h files? I am new to C programming but I thought this concept was easy to grasp, now I am completely confused.

like image 648
John Bozo Avatar asked Jan 14 '13 01:01

John Bozo


2 Answers

If you use the -Wall flag (and one should always use it, along with -Werror -Wextra), then you'd get the following message:

main.c: In function 'main':
main.c:3: warning: implicit declaration of function 'hello'

And the compiler effectively "guesses" what to do, which can lead to disaster in many circumstances.

Correctly using header files avoids this sort of warning.

like image 159
Oliver Charlesworth Avatar answered Oct 12 '22 17:10

Oliver Charlesworth


You do not need header files; instead, your functions need prototypes. When you call hello passing it "world", C figures out that you are calling a one-argument function taking char*, and does everything right. This will not work, however, if the function takes a float, and you decide to ass it an int (try it, it is very instructive). For reasons of backward compatibility C will let you call functions without prototypes, but it is dangerous. For example, in case of your call of hello, the compiler thinks that you are calling a function returning an int. Technically, you are invoking undefined behavior, so your program works by accident.

Headers happen to provide the most convenient way to supply prototypes, but you can supply them in the code itself, like this:

void hello(char*);

int main()
{
    hello("world!");
    return 0;
}
like image 27
Sergey Kalinichenko Avatar answered Oct 12 '22 17:10

Sergey Kalinichenko