Archived

This topic is now archived and is closed to further replies.

headshot

how do multipule cpp files go together

Recommended Posts

now i have been looking at diferent source code and they use a larg number of diferent cpp files. now what i want to know is how does the compiler fit all the diferent files together, i can''t understand how all thefiles are used as one? am i making sence?

Share this post


Link to post
Share on other sites
Every .cpp file is compiled to an .obj / .o file(depending on the compiler). These files are then combined by the linker to create a single excutable.

Every cpp file contains some procedures of the whole program.
Lets say we have a file a.cpp:


void SayHello()
{
puts("Hello");
};


and a file b.cpp

void SayHello();

void main()
{
SayHello();
};


Now the procedure main() in b.cpp calls the procedure SayHello() in a.cpp. But you must(or at least should) tell the compiler that a funcion SayHello() exists somewhere in the project. Therefore you include a prototype (the line void SayHello() in b.cpp). These Prototyes are normally defined in include files, which are files with the extension .h ans are included using #include.

Share this post


Link to post
Share on other sites
Everything in each cpp file can only be accessed by other functions in that file unless they''re also declared as external function / variables using the extern keyword or are given some other way to know they''re there, like member fuctions for classes declared in the header files.

Seperating code is a good idea, it helps keep the code clear. Video stuff in 1 file (or more likely more), sound stuff in one, input in one. It makes finding things alot easier.

The files aren''t actually used as one, the compiler treats them all seperatlym each file creates an object file that the linker links them all together.

Share this post


Link to post
Share on other sites
so what your saying is i need an #include with all the prototypes, and they i can make calls inbetwean files without worrying?

EDIT:does that include globals(vars, handles etc.)

[edited by - headshot on July 27, 2003 9:07:36 AM]

Share this post


Link to post
Share on other sites
Yes you cold create for every .cpp file a .h file in which you declare prototypes for the functions in the file and declarations for the global variables in the file. When this header file is included in the other cpp files you can use the procedures / global variables from the other file.

Yes global variables are declared in the header using extern:


extern int g_Data;


would allow you to use the variable g_Data, which was defined in a other file.

Share this post


Link to post
Share on other sites
Ok, this might come a little bit too detailled, but once you understood how a program looks like "inside the computer", you can derive everything else ...

I won''t be covering everything here, because that would definitely be too much for me to write down ;-), and I''m sure there are plenty of resources in the internet, I''m just trying to explain this topic for you ...

You have to know, that the CPU doesn''t know the name of the variable in your sourcecode, when the compiled program is executed.

Let''s look at an example ... let''s say we have the following C-sourcecode:


int main() {
char a;

a = 5;

return 0;
}


Very simplified, the char variable a is not known as "a", but as a place in the memory to look at. The command "a = 5;" is translated into nothing else than "write the value 5 in the memory at the location where a is".

The compiler replaces all the "a"s in the sourcecode by the adress (which is computed by the compiler as well, but you don''t have to bother about that, lets just assume that the adress of "a" is 120).

so, "a = 5;" gets to "write the value 5 to adress 120".

by defining the variable "a" the compiler knows that he needs to reserve space for a char variable in the memory. as long as the compilation process takes, this location is still referred to as "a". as soon as you link the program, the symbol "a" is replaced by a number holding the location in the memory which was reserved for "a".

this process is quite complicated and i really had to build my own compiler / linker before I fully understood what was going on ;-).

of course, the linker has to know how many space a variable needs and where to find it and so on, and all these things necessary for the linking process are stored in a so-called "symbol-table" created by the compiler.

now going back to your question ... you can look at every .cpp file as a module which is compiled separately. the linking process (as the name suggests), links all the modules together and creates the final executable code. lets say we have two modules (two .cpp/.c files), which should work together, that means that we want to assign a value to a variable declared in the other module. how should the compiler know that this variable exists in another module? well, i won''t bother you with syntactic questions in c, my intention is just to provide you a general survey so you can combine the rest all by yourself. lets just say we tell him that.

as soon as he starts compiling, he notices there''s a reference to a variable which has been declared in another module. and here''s where the symbol-tables are very handy. every module has a symbol-table with all the variables declared. the compiler marks such external variables for the linker, which resolves all the symbol tables and the code the compiler created and links it all together. in the final program, there won''t be a named variable, but an adress in memory (reserved for this variable).

well ... I hope it wasn''t too complicated and for those who already know ... never mind ;-). if you have any questions feel free to google or contact me ...


Indeterminatus

--si tacuisses, philosophus mansisses--

Share this post


Link to post
Share on other sites
You don''t need one .h file for every .cpp.
The h files are only included in cpp file, where the #include command appears. You can use as much h files, as you want. But if you put all prototypes, object definitions and global variables in one big include file it will get very complex and hard to find certain parts.
You can create one .h file, that includes the other .h files, if you want.
But you get problems with the global variables, if you include everything at once, since you have the extern and normal declaration in the same file.
for example you would have:


// From the include file
extern int g_Data;

...

// From the cpp file
int d_Data;


And now the compiler complains, that g_Data ist declared twice. To avoid this, you could either put all globals in a cpp file of their own, or avoid including the file that contains the extern declarations in the cpp file that declares the variables.

Share this post


Link to post
Share on other sites
quote:

hold on, do i need an indivigual .h for every file, or can i just have a master that i add all the prototypes and globals to and #include it in each file?



you can look at it like this ...

lets assume we have the following file inc.h:


void doThis();
void doAnythingElse();


and a .cpp file looking like this:



#include "inc.h"
...
// the rest of the file is not necessary for my purpose now


as soon as the compilation process starts, the compiler does nothing else as inserting the contents of inc.h where it is included by "#include".

the sourcecode which is compiled then looks like this:



// here was the #include-command
void doThis();
void doAnythingElse();

// and here is the rest of the .cpp-file...


to put it in a nutshell: you can have as many header (.h) files as you want, and you can put everything in as you like. the only thing you have to be careful is not to create a cross-reference (that might be, for example a file "a.h" including "b.h" which is including "a.h" ... you get the problem of this?).

but theres a very small trick that allows you to avoid this.

just use a structure in your headerfiles like the following.

in this example, i''ll be using the headerfile "encrypt.h".


// encrypt.h
#ifndef __ENCRYPT_H
#define __ENCRYPT_H

// here''s the place for the stuff you want to place in the header
// file...

#endif


this does nothing else than make sure that this headerfile is included only once.

if you have a sourcecode where this would be:


#include "encrypt.h"
#include "encrypt.h"


the headerfile "encrypt.h" would only be included the first time. i won''t explain you why, if you do not know already, take a look at #ifndef (in the c-help for example).

Indeterminatus

--si tacuisses, philosophus mansisses--

Share this post


Link to post
Share on other sites
this is a little off topic but i have it all set up(a header and 3 cpp)and i go to compile, and for every file it tells me the following for each cpp file(making 6 errors)


c:\documents and settings\reilly\desktop\c++\includes\tricksheader.h(53) : error C2146: syntax error : missing '';'' before identifier ''LRESULT''
c:\documents and settings\reilly\desktop\c++\includes\tricksheader.h(53) : fatal error C1004: unexpected end of file found


the issue is that part of the code is the function prootype in the header, here is the header with the line comented out(i have been basing all the code off the code in the book i''m using right now, "tricks of the windows game programming gurus")




///////////////////////////////////

//the .h file for the TOTWGPG book examples

//////////////////////////////////





//INCLUDES//////////////////////////////

#include <windows.h> // include important windows stuff

#include <windowsx.h>
#include <mmsystem.h>
#include <ddraw.h> //include importent directX stuff

#include <iostream.h> // include important C/C++ stuff

#include <conio.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include <io.h>
#include <fcntl.h>



// DEFINES ////////////////////////////////////////////////


// defines for windows

#define WINDOW_CLASS_NAME "WINCLASS1"

// MACROS /////////////////////////////////////////////////


#define KEYDOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0)
#define KEYUP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1)

// GLOBALS ////////////////////////////////////////////////

HWND main_window_handle = NULL; // globally track main window

HINSTANCE hinstance_app = NULL; // globally track hinstance


char buffer[80]; // general printing buffer



//Prototypes///////////////////////////////////////////////


//main game functions///////////////


int Game_Main(void *parms = NULL, int num_parms = 0)


//windows functions/////////////////


LRESULT CALLBACK WindowProc(HWND hwnd,//this is the line it points to for the error

UINT msg,
WPARAM wparam,
LPARAM lparam)
int WINAPI WinMain(HINSTANCE hinstance,
HINSTANCE hprevinstance,
LPSTR lpcmdline,
int ncmdshow)


//directX, inti and shutdown///////


int Game_Init(void *parms = NULL, int num_parms = 0)
int Game_Shutdown(void *parms = NULL, int num_parms = 0)




Share this post


Link to post
Share on other sites
You need a ; on the end of each function decleration.

You''re also including the header file too oftern if it keeps coming up. Use either the defines like Indeterminatus mentioned or put :

#pragma once

at the top of the header file.

Share this post


Link to post
Share on other sites