C++ Linker Problems

Can anyone recommend me a site or .pdf where I can learn more about compiling and linking code? All they really taught me in school was C++ syntax and coding style which I'm fairly comfortable with. I keep having problems with my includes and the linker. I also never really learned about things like resources or including libraries or other dependencies. Does anyone know of some good resources?

While I'm asking, I might as well get some advice about a bug I've been having. One of my source files doesn't seem to be able see it's includes. The source is something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Game.h
#ifndef GAME_H
#define GAME_H

#include "../Globals.h"

using namespace My_Project;

namespace My_Project
{
    class Game
    {
        My_Project::Bitmap bitmap;
    public:
        Game() {};
    };
}

#endif 


This gives me errors like so:
1>d:\Path\Templates\Game.h(16): error C2039: 'Bitmap' : is not a member of 'My_Project'
1>d:\Path\Templates\Game.h(16): error C2146: syntax error : missing ';' before identifier 'bitmap'
1>d:\Path\Templates\Game.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>d:\Path\Templates\Game.h(16): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int

This error shows up multiple times, in almost every CPP That uses the Project::Bitmap class and a few that don't. Commenting out the line "My_Project::Bitmap bitmap;" makes everything work fine.

"Globals.h" is basically the root of an include tree that includes everything in the project. Globals.h includes a header file for each of the directories above it. Each of these header files in turn includes "Globals.h" and a header file for each of the directories above it (Where the process continues), a class prototype of every class in that directory in the My_Project namespace, and finally includes for the header file corresponding to each class.

Pretty much every other right now is in a directory called "Engine" and every other file seems happy with the #include tree. Game.h is in it's own directory "Templates" and does not. Can anyone suggest a reason for this error? I would be happy to supply more details.
First, these aren't linker errors. These are compiler errors.

On line 13, you say you want to declare a member of type My_Project::Bitmap, but I see no type called Bitmap inside the My_Project namespace.
Bitmap is in the My_Project namespace. It is defined in another file it works like this:

1
2
3
4
5
6
7
8
// Globals.h
#ifndef GLOBALS_H
#define GLOBALS_H

#include "Templates/Game.h"
#include "Engine/Engine.h"

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Engine.h
#ifndef ENGINE_H
#define ENGINE_H

#include <Windows.h>
#include "GL/gl.h"
#include "../Globals.h"

namespace My_Project
{
    class State_Unit;
    class Video_Unit;
    class Audio_Unit;
} 

#include "System/GL_Window.h"
#include "Video/Video.h"

#include "State_Unit.h"
#include "Video_Unit.h"
#include "Audio_Unit.h"

#endif 



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Video.h
#ifndef VIDEO_H
#define VIDEO_H

#include "../Engine.h"

namespace My_Project
{
    struct  fRGBA;
    struct  Selection;
    struct  Bitmap;
    class   Texture_Manager;
    class   GL_Renderer;
}

#include "fRGBA.h"
#include "Bitmap.h"
#include "Selection.h"
#include "Texture_Manager.h"
#include "GL_Renderer.h"

#endif 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Bitmap.h
#ifndef BITMAP_H
#define BITMAP_H

#include "Video.h"
#include <string>

using namespace My_Project;

struct My_Project::Bitmap
{
    std::string     file_name;
    GLuint          id;
    unsigned int    width;
    unsigned int    height;
    unsigned char*  data;

    Bitmap( const char* a_file_name );
    ~Bitmap();
    void Bind();
};

#endif 


Thus, theoretically there should be no problem in seeing Bitmap.h, this is just rather a larger project than I'm used to writing.
Last edited on
You appear to have an order of #include issue.

Globals.h includes engine.h at line 6.
-- engine.h includes video.h at line 17.
---- video.h has an include of engine.h at line 5 which is effectively ignored.
---- video.h references struct Bitmap at line 11. struct Bitmap is undefined at this point.
---- video.h has an include of bitmap.h at line 17, but this is too late.
Last edited on
You should have every header blindly include all other headers. It causes problems like the one you are seeing.

Here's an article I wrote a while back which goes over pitfalls and how all of this works:
http://www.cplusplus.com/forum/articles/10627/
Apart
Having using namespace in a header defeats the purpose of having namespaces
As the others says those are compiling and not linking errors.
However I will focus mainly to your first question (expanding the answer... including also "compiling phase").

1) Rationalize your includes

Try to avoid "all-in-one" includes like your header files "Game.h" and "Globals.h" if not really necessary.

for example, in my opinion....

1
2
3
4
  //Good_example.cpp
  #include <string>
  #include "Image.h"
  //now code.... it will use std::sting and my_project::Image inside 


1
2
3
  //bad_example.cpp
  #include "MIXED_GROUP_HEADERS.h"
  //now code.... it will use std::string, my_project::Image, my_project::Sound etc etc 


The second code is worst becouse:
1) You will risk to bind yourself to include headers also inside files where they are useless
2) You will have more problems to mantain your code (becouse you can be forced to change that header(s) ... that will become longer and longer, or too complexy structured, and you will risk to "don't understand what your include will really implement"

It is not, instead, a bad idea (so it is a good idea) to include headers inside an header when they are "dependecies".... so in your example it could be a good Bitmap.h in this way

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Bitmap.h
#ifndef BITMAP_H
#define BITMAP_H

#include <string>
//including header here that defines GLuint 
//(sorry I don't use GL so I cannot say it myself) instead of general_purpose "Video.h"

namespace My_Project {
  struct Bitmap
  {
      std::string     file_name;
      GLuint          id;
      unsigned int    width;
      unsigned int    height;
      unsigned char*  data;

      Bitmap( const char* a_file_name );
      ~Bitmap();
      void Bind();
  };
}
#endif  


1
2
3
  //in .cpp
  #include "Bitmap.h"
  //include all_other_headers_you_require_for_cpp 


As you can see in header I will include only headers that are strictly needed to be sure that every line can be understood by the compiler. In your class definition you use only std::string and GLuint, a part primitive types, so that header "depends" only by the header that defines "std::string" and header that defines "GLuint".
It will be your responsability to include in .CPP every other includes you will need (but avoiding general-purpose-includes.... trying to focus what you will really need).... for example you could need to use std::ifstream.h and in that case you could need to include <iostream> and <fstream> in .cpp

---------

2) Avoid to re-write things that probably exists

Perhaps a "Bitmap" like the one you are trying to develop still exists... I don't know GL programming, so I am not sure about it...

-------------

3) learn to use g++ directly from command line

It is harder than using a GUI, and perhaps less confortable when you must find an error but..... you will have more control and you will understand (and manage) better how to control every compiling step (compiling and linking)

---------------------------

Final note: as someone rightly says.... never use "using namespace" inside a header.... see my first code snippet....

for another example I made using namespace, you can see this example I made: http://nobun.users.sourceforge.net/BinaryStream.zip

However take mind that I am a "non professional programmer".... I do programs only for fun... I never learned programming in school (I learn all I know by myself... and asking around) and my "work" does not involve programming at all
Last edited on
Disch: I've read your article, and I'm sure I'm going to look like a fool quibbling with what I'm sure ARE best practices, but out of curiosity, why isn't it a good idea to put all my header includes in one big file? I understand that it might better document what a class does for it to only include what it absolutely needs, but in my experience it makes re-factoring code more difficult:

If a class is refined to play a slightly different role, it's helpful to rename it (and the header file) so that it remains clear what it does. Likewise, from time to time I feel the need to reorganize my directories to make it more obvious what the relationship between components are. But then, the #include statement in every dependent file would need to be updated (Note only the file name, but also it's relative path, which can get quite complicated).

All: Why shouldn't a using namespace directive be used in a header file? Everything in the module has the same namespace. The utility of the namespace only comes into play outside the module where there might be ambiguities.
include all of your header files into globals.h and access them by including globals.h in your cpp files
this can help's you dirring the development
dont use namespaces in header files
this is ugly in my idea because:
you can't undo that process
dont rewrite a structure
and a question i have:
what compiler do you use?
for namespace in header.
If you define a namespace "MyPrg" and in the same header you will add an "using namespace MyPrg" this is what will happen:

1) when you will include your header file, MyPrg namespace is just "ignored"... this becouse you will include also "using namespace" so all files that access to that header will have access to "MyPrg::x" simply putting "x"........ so, in that situation, you could simply avoid namespaces becouse they will, in practice, ignored.

2) in case of multiple file with same namespace you could define several time the same "using namespace"... not good, imho

3) When you declare "using namespace" inside a cpp, instead, you include a "shortcut" for that namespace only in that cpp you really need.... so, when other files will include "MyPrg::x" they will need to access it as "MyPrg::x" or provide explicitly an "using namespace MyPrg"

------------


If a class is refined to play a slightly different role, it's helpful to rename it (and the header file) so that it remains clear what it does. Likewise, from time to time I feel the need to reorganize my directories to make it more obvious what the relationship between components are. But then, the #include statement in every dependent file would need to be updated (Note only the file name, but also it's relative path, which can get quite complicated).

It is absolutely the opposite...
If your project is little, then your idea can be easy to mantain and spare your life....
...but if your project become bigger.... it will become harder to mantain.

First of all... think every cpp file like a "separated module" that does a specify task.
It is easier to mantain if you have full control of it, including directly headers it will need, instead of giving it a general header that will control all other things (with possible conflicts).


Note only the file name but also it's relative path

if you use g++ you can use the -I option to specify default path(s) for inclusion....in theory (usually you will not do it becouse you would uso automake cmake, scons or similar more than "make" directly) you could specify different -I options for every source file
Ah, I was under the impression that using namespace only worked at file scope. It seems I was grossly mistaken. I concede the point.

I'm actually using Visual Studio 2010. To be honest, I don't know much more about the compilation process than that I hit the build button and it compiles if my code is written correctly.

As for G++... I don't know anything about the GNU Compiler Collection or where I would even begin to start looking at it. I'm open to learning, but I'd need to find the right to tutorial to pick it up.
I think that learn to use g++ from command line (at basic level... I am not expert too on using g++) helps you to understand better how compilation works, becouse you are forced to understand every step you are doing.

However I cannot answer deeply to your question, in this starting step. Now I will explain what I mean...

"What compiler is better...?" -> it depends of situations. I don't use visual studio becouse I am more oriented to develop platform-independant applications but also becouse I hate the fact I am forced to register it to activate it.
But, saying that, if you develop win-only applications, perhaps visual studio is a good choice.

Another problem: unlike linux, windows is not well suited for compilation. You need to work and setup your compile-toolchain (setting path variable accordingly, etc etc).

So, when you try to use gcc/g++ you can be discouraged becouse: 1) You must find a Mingw-gcc version up to date (2) you must "configure path and MINGDIR" (3) gcc and gdb themselves are not so easy to use, at start.

The advantage of gcc is.... it is supported both in linux (default compiler) and Mac.
Another advantage is that it is recognized by scons (google... to see what scons is).
Perhaps scons recognize also Visual Studio, probably (I don't know) if you try to provide an "independant" building script

But... also becouse of configuration problems, sometimes can still be easier to provide a personal Makefile (ready to use) to compile your own windows version...

.....so, after this short introduction... you can have a little view of possible problems.

If you are interested I can provide you a little guide here for the VERY VERY basic usage og g++

----------------------------------------
G++ VERY Basic Use
----------------------------------------

I - Compiling
-----------------------------------

 
g++ -c -o module.o module.cpp

This first example shows you the first 2 options to know when you compile.
-c: this options says that g++ will compile only (so no linking phase at the moment)
-o <name>: this option specify output file name (in this case module.o)
module.cpp: the actual parameter outside options.... the file to process (sourcefile)

 
g++ -c -DDEFINED_MACRO -I. -I"c:/mylib_dir/include" -o module.o module.cpp

This example is a bit more complex. It will use also -D and -I options
-D and -I requires that you specify their parameter WITHOUT ANY SPACE
so... IMMEDIATELY after -D and -I you must specify the option
so...... -DDEFINED_MACRO means that "DEFINED_MACRO" is the parameter of option -D
and the same for -I (note: in the second example I used quotes... they are usefull if your directory contains spaces)

now the meaning
-D: defines a macro.... in my example with -DDEFINED_MACRO I obtain the same result like as I wrote "#define DEFINED_MACRO" inside module.cpp (or one of its headers). This option is useful when you must distinguish DEFINES, for example, depending of OS used

-I:add an include path. Very much used (more used than option -D) and very useful. In my example I added 2 include paths (one for every -I)... the first one is "current directory" (so... where module.cpp is)... all headers inside those directories will be found also using #include <FILE>

--------------------------
Linking
--------------------------

 
g++ -o test.exe module.o main.o

The grammar is always the same... in this case we will NOT use option -c (becouse it is linking phase) and we will produce "test.exe"
The interesting thing is that sources are multiple here... so it will be simply a list of (precompiled) .o files

 
g++ -L.  -lmylib -o test.exe module.o main.o

the two options more used are -L and -l
-L specify a PATH where to find a library (in my example library will be searched also in current directory)
-l specity the library to link to. With -lmylib gcc will search for a mylib.a or mylib.dll (under windows) in your library paths, including the current dir (added with option -L)

----------------

for the moment I would avoid optimization, etc etc. I think it is enough to start.
Ah, I was under the impression that using namespace only worked at file scope. It seems I was grossly mistaken. I concede the point.

It does - but when you #include a header file, you make the contents of that header part of the file. The pre-processor literally takes the contents of the header file and inserts it into the source code at the point where the #include statement is, and then the compiler compiles the results of that insertion.

So when you have a using namespace statement in a header file, then that statement becomes part of every single other file that includes that header, which means that you have pulled that namespace into every single one of those other files.

And, of course, if you're doing your "one big global header" thing (and let me add my voice to those saying "don't do that!"), it means every single one of your source code files is going to have that using namespace statement in it.
> But then, the #include statement in every dependent file would need to be updated
The idea is to compile all the sources into object files and then link them together.
Suppose that a source change, then you just recompile only that source and relink.

┬┐What if a header changes? An #include is just copy-paste, so that means that all the dependent files would need to be recompiled.

Having those fake dependencies would make you recompile files that you didn't need to.
So you simply don't benefit from the two stage build process, you better just do
$ g++ *.cpp -o program.bin



Compilation time may be significant (by instance `CImg.h')
Topic archived. No new replies allowed.