Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Question regarding header files

Credits go to Audric and Peter Hull for helping out!
This thread is locked; no one can reply to it. rss feed Print
Question regarding header files
Bob Keane
Member #7,342
June 2006

This is either a stupid question or a stupid programmer. I am following the tutorials but running into a problem. I copied the code from this tutorial on creating a full screen display. It works, but I want to make it a header file. When I copy the code to a header file and compile, I get an "defined reference to disp_data" error. I did copy the ALLEGRO_DISPLAY_MODE disp_data statement into the file. What am I doing wrong?

By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul.
If we get apple juice from squeezing apples, and we get prunes from drying out plums, where does prune juice come from?
Since gasoline contains ethanol, can self driving cars get duis?

Peter Hull
Member #1,136
March 2001

Would be helpful if you posted the actual header file.

Probably the reason is, if you have

in a header file, that will put a separate definition of disp_data into every C file that includes it. So when you link, you will get multiple definition errors. Is that what you're seeing?
The solution would be to declare it as extern in the header and have one C that has the actual definition.

Audric
Member #907
January 2001

Bob Keane said:

This is either a stupid question or a stupid programmer

Well, it seems dubious that you would really need to "make it a header". The instructions for setting a graphic mode have to end up in a function (main() or any other), and this function has to end up in a C or CPP file that you compile and then link.
What a header file typically contains is:
- macros and #define-ed constants
- function declarations (signatures only: the body { ... }is replaced by a ; )
- enums
- typedefs and structs (very often used together)
- enums
- extern declarations, if you need any

- never a full function
- never any variable

Bob Keane
Member #7,342
June 2006

Thanks for the replies. The reason I want to put it in a header file is because I want to write a two player game and write duplicate code for the server and client. I guess there are no stupid questions, just stupid programmers.

By reading this sig, I, the reader, agree to render my soul to Bob Keane. I, the reader, understand this is a legally binding contract and freely render my soul.
If we get apple juice from squeezing apples, and we get prunes from drying out plums, where does prune juice come from?
Since gasoline contains ethanol, can self driving cars get duis?

Doctor Cop
Member #16,833
April 2018
avatar

Bob : By your comment I guess you don't know how networking works.
Don't worry nobody knows from start, just try some "Chat program in C/C++" on YouTube then you'll have Idea of what it actually is and how it works.

bamccaig
Member #7,536
July 2006
avatar

Bob, take a look at this wiki article (doesn't seem to be on the Github wiki though):

https://wiki.allegro.cc/index.php?title=Header_file

That explains how and why to use header files. What you effectively want to do is turn your common code into a "library" of sorts. You can do this, but it's important to understand the purpose of the header file versus the source file. The variables and functions need to go in the source file. The header file is just for declarations (hints to the compiler that things exist either in other source files or later on in this one).

common.h#SelectExpand
1// extern makes this a declaration; no variable exists in memory for it yet, but 2// this declaration promises that there will be one. 3extern ALLEGRO_DISPLAY * display; 4 5// Similarly, a function declaration promises that the function will exist somewhere 6// later on, but so far it hasn't been defined. 7int setup_allegro();

(Header guards withheld to keep things simpler for the discussion)

common.c#SelectExpand
1// This actually allocates memory for the variable in the program. 2ALLEGRO_DISPLAY * display; 3 4int setup_allegro() { 5 // Contrived example.. 6 7 if(!al_init()) return 0; 8 if(!al_install_keyboard()) return 0; 9 10 display = al_create_display(1024, 768); 11 if(!display) return 0; 12 13 return 1; 14}

client.c#SelectExpand
1#include "common.h" 2 3int client() { 4 setup_allegro(); 5 6 return 0; 7} 8 9int main(int argc, char * argv[]) { 10 return client(); 11}

server.c#SelectExpand
1#include "common.h" 2 3int server() { 4 setup_allegro(); 5 6 return 0; 7} 8 9int main(int argc, char * argv[]) { 10 return server(); 11}

You can either setup the programs as two separate projects, compiling "common.c" twice, or you can compile common.c into a library (static or dynamic) and link to it from each program. The easiest thing is to just compile it again in each program, but you need to keep in mind that when you make changes to it you need to recompile all the programs that use it again. Whereas if you were to create a dynamic library for it then you could just update that library file and as long as signatures haven't changed existing programs can load the new code without recompiling.

Go to: