Hey, so I have a file I use to store my own math functions called MyMath.h. I included MyMath.h in my main.cpp file and it worked fine. But then I tried including it to another file, and I get this error:

Block.obj : error LNK2005: "int __cdecl Random(int,int,bool)" (?Random@@YAHHH_N@Z) already defined in main.obj

Why is that happening? I have the code in the header surrounded by an #ifndef, if that might be it.

Here's MyMath.h:

#ifndef MY_MATH_H
#define MY_MATH_H

int Random(int my_min = 0,int my_max = RAND_MAX,bool use_complex = false);
int Complement(int angle);
int Suplement(int angle);
double Angle(double in_angle,bool use_degrees = true);

#define PI 3.14

int Random(int my_min, int my_max,bool use_complex)
{
	int result = 0;
	if(use_complex == false)
	{
		int range = my_max-my_min;
		result = rand()%(range+1) + my_min;
	}
	else if(use_complex == true && my_min < my_max)
	{
		do
		{
			result = rand();
		}
		while(result < my_min || result > my_max);
	}
	return result;
}

double Angle(double in_angle,bool use_degrees)
{
	double max_angle = use_degrees ? 360.0 : 2.0*PI;

	while(in_angle >= max_angle)
		in_angle -= max_angle;
	while(in_angle < 0)
		in_angle += max_angle;

	return in_angle;
}

int Complement(int angle)
{
	angle = Angle(angle);
	while(angle > 90)
		angle -= 90;
	return 90-angle;
}

int Suplement(int angle)
{
	angle = Angle(angle);
	if(angle > 180)
		angle -= 180;
	return 180-angle;
}

#endif

The line #include "MyMath.h" is found in the top of both main.cpp and Block.h. Block.cpp is what was complaining.

Recommended Answers

All 9 Replies

what is wrong is that you should not put executable functions in header files, unless they are methods in a c++ class. you can put those functions in your own class

class MyMath
{
public:
// put your functions here

};

Would it work if I separated the implementation into a different .cpp file (ie, MyMath.cpp)? Because I'd rather not put MyMath. in front of every one of my math functions.

Also, what is an executable function? Are there non-executable functions? And why would putting them in a class fix whatever the problem is?

EDIT: I tried separating the definitions and that worked, but I have another problem.

Block.obj : error LNK2001: unresolved external symbol "protected: static class Texture * Block::m_img4" (?m_img4@Block@@1PAVTexture@@A)
Block.obj : error LNK2001: unresolved external symbol "protected: static class Texture * Block::m_img3" (?m_img3@Block@@1PAVTexture@@A)
Block.obj : error LNK2001: unresolved external symbol "protected: static class Texture * Block::m_img2" (?m_img2@Block@@1PAVTexture@@A)
Block.obj : error LNK2001: unresolved external symbol "protected: static class Texture * Block::m_img1" (?m_img1@Block@@1PAVTexture@@A)

I get these errors. the m_img... variables are members of a Block class (declared in Block.h and implemented in Block.cpp), and Texture is a wrapper class for the IDirect3DTexture9 struct (declared and implemented in Texture.h and Texture.cpp)

Block.h:

#ifndef BLOCK_H
#define BLOCK_H

#include "Object.h"
#include "Texture.h"
#include "MyMath.h"
#include <d3d9.h>

class Block : public Object
{
public:
	Block();
	~Block();
	static int SetBlockImages(IDirect3DDevice9* d3ddev,char* img1,D3DCOLOR transcolor1,char* img2,D3DCOLOR transcolor2,char* img3,D3DCOLOR transcolor3,char* img4,D3DCOLOR transcolor4);
	int SetImage();
protected:
	static Texture* m_img1;
	static Texture* m_img2;
	static Texture* m_img3;
	static Texture* m_img4;
};

#endif

Texture.h:

#ifndef TEXTURE_H
#define TEXTURE_H

#include <d3d9.h>
#include <d3dx9.h>

class Texture
{
public:
	Texture();
	~Texture();
	int InitTexture(char* filename,D3DCOLOR transcolor,IDirect3DDevice9* d3ddev);
	int Draw(float x,float y,float rotation,ID3DXSprite* sprite_handler);
	IDirect3DTexture9* GetTexture();
	D3DXIMAGE_INFO GetImageInfo();
	int GetWidth();
	int GetHeight();
private:
	IDirect3DTexture9* m_d3dTexture;
	D3DXIMAGE_INFO m_imgInfo;
};

#endif

<< Block.obj : error LNK2001: unresolved external symbol "protected: static class Texture *
<< Block::m_img4" (?m_img4@Block@@1PAVTexture@@A)

class Block : public Object
{
public:
	Block();
	~Block();
<snip>
protected:
	static Texture* m_img1;
	static Texture* m_img2;
	static Texture* m_img3;
	static Texture* m_img4;
};

// outside your class initialize the static member variables ...
Texture* Block::m_img1 = 0;
Texture* Block::m_img2 = 0;
Texture* Block::m_img3 = 0;
Texture* Block::m_img4 = 0;

I'm away from my home computer right now, but I'll try that when I get home.

But wouldn't code like that be placed in a constructor? And aren't you redifining the type of the variable as Texture*? Why is that redefinition neccesary? I'm a little confused as to what exactly is causing the errors.

>>Also, what is an executable function? Are there non-executable functions?
what I really meant is a function that contains code, as opposed to a function prototype. All you put in header files are defines, classes, and function prototypes. The actual implenentation of those function are put in an implementation *.cpp file.

When you put implementation code in a header file, then include the header file in two or more *.cpp files the compiler will attempt to copy the function into each of the *.cpp files, and the linker will produce duplicate definition errors.

>>And why would putting them in a class fix whatever the problem is?
When used within a class there is only one copy of the implementation functions regardless of the number of instances of the class.

You might also consider implementation of inline functions. To use them just add inline keyword to the front of the function names in the header file that you have already written.

When you put implementation code in a header file, then include the header file in two or more *.cpp files the compiler will attempt to copy the function into each of the *.cpp files, and the linker will produce duplicate definition errors

Then what is the purpose of surrounding the code in header files with #ifndef? I thought that prevents the code from being executed twice or something.

Also, is #define old functionality left over from C, and you should usually use const variables and inline functions?

Then what is the purpose of surrounding the code in header files with #ifndef? I thought that prevents the code from being executed twice or something.

Code guards do not do that -- they only prevent including of a header file more than once from within the same *.cpp file. Some header files include other header files, and sometimes the same header file can be included in more than one header file. Code guards prevents duplicate declarations because of this.

Also, is #define old functionality left over from C, and you should usually use const variables and inline functions?

Yes, that is a fair assumption. const variables are preferred over #defines

<< Block.obj : error LNK2001: unresolved external symbol "protected: static class Texture *
<< Block::m_img4" (?m_img4@Block@@1PAVTexture@@A)

class Block : public Object
{
public:
	Block();
	~Block();
<snip>
protected:
	static Texture* m_img1;
	static Texture* m_img2;
	static Texture* m_img3;
	static Texture* m_img4;
};

// outside your class initialize the static member variables ...
Texture* Block::m_img1 = 0;
Texture* Block::m_img2 = 0;
Texture* Block::m_img3 = 0;
Texture* Block::m_img4 = 0;

I added both this:

Texture* Block::m_img1 = 0;
Texture* Block::m_img2 = 0;
Texture* Block::m_img3 = 0;
Texture* Block::m_img4 = 0;

and this:

Block::m_img1 = 0;
Block::m_img2 = 0;
Block::m_img3 = 0;
Block::m_img4 = 0;

Right after the declaration of the Block class in Block.h, and neither worked (the first complained about redefinitions, and the second complained about missing variable types).

I also tried replacing the code in the Block constructor from

m_img1 = new Texture;
m_img2 = new Texture;
m_img3 = new Texture;
m_img4 = new Texture;

To:

m_img1 = 0;
m_img2 = 0;
m_img3 = 0;
m_img4 = 0;

and allocated the memory elsewhere, but that also didn't work.

Any else know what could be wrong?

Ehh, I ran into yet another problem. I really think I don't understand something (or things) that are very fundamental in using header files that's causing me to get all these errors every time I try to do something that I think is very simple.

I have this code in a header file Graphics.h:

extern IDirect3D9* d3d;
extern IDirect3DDevice9* d3ddev;
extern IDirect3DSurface9* back_buffer;
extern ID3DXSprite* sprite_handler;

At first I didn't have the extern keyword, and then I had issues with the linker. It told me I was trying to redefine these and other variables in another header file (Input.h). I tried adding the static keyword to them (not because I understood the problem and I thought that would help, but because I looked at MSDN and some other sources and I had a hunch that making them static might help. I did that and the project compiled, but then I had issues with code that worked fine when it was all in one file. The window would appear but it wouldn't accept input (the only thing I had it set up to do was to exit the program when the user pressed escape). I isolated the problem and found that d3ddev was evaluating to NULL, which resulted in the game loop function not running. I thought that this had something to do with the static keyword, so I replaced it with extern (which, again, seemed like a good idea based on examples from sites and a book of mine), and I get these errors:

Main.obj : error LNK2001: unresolved external symbol "struct ID3DXSprite * sprite_handler" (?sprite_handler@@3PAUID3DXSprite@@A)
Graphics.obj : error LNK2001: unresolved external symbol "struct ID3DXSprite * sprite_handler" (?sprite_handler@@3PAUID3DXSprite@@A)
Main.obj : error LNK2001: unresolved external symbol "struct IDirect3DDevice9 * d3ddev" (?d3ddev@@3PAUIDirect3DDevice9@@A)
Graphics.obj : error LNK2001: unresolved external symbol "struct IDirect3DDevice9 * d3ddev" (?d3ddev@@3PAUIDirect3DDevice9@@A)
Graphics.obj : error LNK2001: unresolved external symbol "struct IDirect3D9 * d3d" (?d3d@@3PAUIDirect3D9@@A)
Graphics.obj : error LNK2001: unresolved external symbol "struct IDirect3DSurface9 * back_buffer" (?back_buffer@@3PAUIDirect3DSurface9@@A)
Input.obj : error LNK2001: unresolved external symbol "struct IDirectInputDevice8A * dimouse" (?dimouse@@3PAUIDirectInputDevice8A@@A)
Input.obj : error LNK2001: unresolved external symbol "struct IDirectInputDevice8A * dikeyboard" (?dikeyboard@@3PAUIDirectInputDevice8A@@A)
Input.obj : error LNK2001: unresolved external symbol "struct IDirectInput8A * dinput" (?dinput@@3PAUIDirectInput8A@@A)
Input.obj : error LNK2001: unresolved external symbol "int * dikeys_prev" (?dikeys_prev@@3PAHA)
Input.obj : error LNK2001: unresolved external symbol "char * dikeys" (?dikeys@@3PADA)

From what I understand, none of the files can understand what any of the variables I declared extern are (it's worth noting that I have no idea what .obj files are). I don't see how this is possible, seeing as how I define them clear as day in Graphics.h, so they should at least be known to Graphics.obj, but the compiler seems to be more imaginative than I am, and so finds a way to not acknowledge the existence of those variables. (sorry if I sound frustrated/sarcastic. if I do, it's because I am frustrated, especially since it seems as if I've tried to deal with this type of problem 100 times, yet even with the knowledge gained from the times I have solved the problem, I still run into linker errors on the simplest things).

So, anyone know what's up? I am really getting ticked off at linker errors. Why can't the compiler understand what variables that I declare in a header file are? Why wouldn't it work at first without the static or extern keywords. And if anyone happens to know the magical tidbit (or tidbits) of knowledge that I seem to be lacking that causes me to keep running into these errors, please do share.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.