CodingBeagle
CodingBeagle

Reputation: 1960

Need some advice on C header inclusion

Introduction

I'm an experienced programmer and have years of experience with the object-oriented paradigm. Lately I've decided to try and be more familiar and comfortable with languages a bit lower-level than languages such as C# or Java, so I'm delving into C, and will attempt to create some games with it.

Everything is going pretty well, and now I'm attempting to organize my code better by moving function definitions into separate .c files. This is where I start getting uncomfortable, due to the nature of inclusion in C. I'm quite familiar with how it works, and also with the preprocessing stage during compilation. The problem is I'm still not sure I'm dealing with this correctly.

I think my problem resembles what has been asked here. Though it did not fully satisfy what I need to know.

The Problem

Essentially, I'm creating an OpenGL project using two libraries. One is glew (For OpenGL function loading), and the other is GLFW (for window handling and OpenGL context creation). I have two .c files, one called main.c and another called windowInitialize.c. The problem is, both main.c and windowInitialize.c depends on the glew and glfw libraries.

In my main.c file I do the following includes:

#include "includes/GLEW/glew.h"
#include "includes/GLFW/glfw3.h"
#include "windowInitialize.h"

Furthermore, main.c do the following relevant function calls:

if (!initializeGLFW())
 return -1;

GLFWwindow *window = createOpenGLWindow(3, 3, 640, 480, "Hello OpenGL");

/* It is important that we initialize glew AFTER initializing GLFW and setting up
the OpenGL context, as GLEW needs a current context to work */
initializeGLEW();

windowInitialize.c includes the definitions for the functions initializeGLFW and initializeGLEW, as well as createOpenGLWindow. The main.c source though still uses both glew and glfw for main loop purposes, referring to functions and such from both.

Now, windowInitialize.c does these includes:

#include "windowInitialize.h"
#include "includes/GLEW/glew.h"
#include "includes/GLFW/glfw3.h"
#include <stdio.h>

Then proceeds to fill out the function definitions. So there's the deal. Both files need to make use if the glew and glfw libraries, as well as stdio actually (for printing debugging messages and such).

I feel this isn't the right way to do it, but I'm not sure. I believe the reason the compiler/linker is not complaining about double declarations is because main.c and windowInitialize.c gets individual object code files.

My question is though, is the linker clever enough to only put these declarations in the executable file once? So that even though I include these headers several places, it won't have any effect on file size and such? And is this even the correct way of handling common dependencies between several source files? Or should I use another approach?

Upvotes: 3

Views: 140

Answers (2)

zubergu
zubergu

Reputation: 3716

Linker will only use those functions from library that You actually use and it does it once. As for the approach, in book I'm reading atm suggestion is to make a file with all libraries, function declarations, definitions and include only that one file, called eg. mydefinitions.h , instead of doing it separately in every single file of Your project. Hope it helps.

Upvotes: 1

Carl Norum
Carl Norum

Reputation: 225242

Everything you've described seems like the normal way to do things. Your two compilation units are only getting the same forward declarations of functions in those headers, not actual duplicate definitions from the libraries.

My question is though, is the linker clever enough to only put these declarations in the executable file once?

The linker certainly doesn't care what header files you include - it's a linker, not a compiler.

So that even though I include these headers several places, it won't have any effect on file size and such?

Extra/unused forward declarations of functions will have no effect on binary size.

And is this even the correct way of handling common dependencies between several source files?

Yes, you seem to be doing things in a completely normal way.

For your project, you should be doing something like:

cc -c -o main.o main.c                           # compile main.c
cc -c -o windowInitialize.o windowInitialize.c   # compile windowInitialize.c
cc -o myProgram main.o windowInitialize.o -lglew -lglfw # link objects with necessary libraries to create executable

But, really, using a makefile would be better:

myProgram: main.o windowInitialize.o
    cc -o $@ $^ -lglew -lglfw

Example of using it:

$ make
cc    -c -o main.o main.c
cc    -c -o windowInitialize.o windowInitialize.c
cc -o myProgram main.o windowInitialize.o -lglew -lglfw

Upvotes: 6

Related Questions