Search code examples
cincludeheader-files

Which file should include libraries in my c project?


I'm writing a Pong game in C using ncurses. I placed function definitions for the ball, the player, and the AI opponent into ball.c, player.c, and ai.c respectively. Each of these files includes another file, pong.h, which contains function prototypes, structure definitions, and global variables. My main function is in pong.c, which provides the game loop and handles keypresses.

My project also includes a number of libraries: ncurses.h, stdlib.h, and time.h. Where should I include these libraries? Currently, they are included in pong.h, like so:

#ifndef _PONG_H
#define _PONG_H

#include    <ncurses.h>
#include    <stdlib.h>
#include    <time.h>

/* everything else */

#endif

However, only certain files make use of functions in stdlib.h/time.h. This leads me to believe that it might make more sense to only include one-use libraries in the file where they are used. On the other hand, including all libraries in one place is more straightforward.

I'm wondering if there is a way to do this which is considered more conventional or efficient.


Solution

  • There is no firm rule, instead you should balance convenience and hygiene. You're already aware that the meta include is more convenient for your other .c files, but I'll emphasize some more obscure concerns with header files:

    • Putting dependencies (e.g. ncurses.h) in your public header files may make it more difficult to include your header file in other projects
    • The transitive costs of header files will dominate compile time, so reducing unnecessary includes will allow your project to compile more quickly. Programs have been developed to manage includes.
    • Header files can destructively interfere with each other, for instance because of macros that change the semantics of subsequently included header files. windows.h is probably the most notorious culprit, and the risks can be difficult to quantify for large header files or large sets of header files.
    • Over time it can become obvious what header files should actually be bundled, e.g. when the convenience benefit is high and the risks and costs are low. On a small project perhaps it is obvious from the outset.