Hi i get a not so awesome error when I use this piece of code in my header.
It's something with void object::set_values(int a, int b, int c, int d) that fuck it up but I have no idea why :(
[code]
class object
{
public:
float x;
float y;
float width;
float height;
void set_values(int,int,int,int);
};
void object::set_values(int a, int b, int c, int d)
{
x = a;
y = b;
width = c;
height = d;
}
[/code]
Errors:
[code]
Error 25 error LNK2005: "public: void __thiscall object::set_values(int,int,int,int)" (?set_values@object@@QAEXHHHH@Z) already defined in 3DMath.obj main.obj
Error 26 error LNK2005: "public: void __thiscall object::set_values(int,int,int,int)" (?set_values@object@@QAEXHHHH@Z) already defined in 3DMath.obj texture.obj
Error 27 1 fatal error LNK1169: one or more multiply defined symbols found C:\Documents and Settings\Jimmie Nilsson\Mina dokument\Visual Studio 2008\Projects\2d_engine1_0.0.2\Debug\2d_engine1_0.0.2.exe
[/code]
It looks like you're including the header multiple times.
Try using include guards:
[cpp]
#ifndef YOURHEADERFILE_H
#define YOURHEADERFILE_H
// ..
#endif
[/cpp]
here's the whole code in my header:
[url]http://pastebin.com/m1c7e92b3[/url]
I'm using
#ifndef H_MAIN_
#define H_MAIN_
// ..
#endif
so it should work ? :O
void set_values(int,int,int,int);
should be:
void set_values(int a, int b, int c, int d);
[QUOTE=Corewarp3;19893712]void set_values(int,int,int,int);
should be:
void set_values(int a, int b, int c, int d);[/QUOTE]
I use this class in another project and then there's no errors.
It's looks pretty wrong to me.
The program compile without any errors if I delete the set_values function...
Does 3dMath.h or texture.h include whatever that file is?
If so you might have a circular dependency problem which you'll need to forward declare to fix.
[QUOTE=t0rento;19894034]Does 3dMath.h or texture.h include whatever that file is?
If so you might have a circular dependency problem which you'll need to forward declare to fix.[/QUOTE]
I include #include "main.h" in 3DMath.cpp and texture.cpp
I dont include any headers in their header files.
Include it in 3dMath.h and texture.h instead of *.cpp
[QUOTE=Corewarp3;19893712]void set_values(int,int,int,int);
should be:
void set_values(int a, int b, int c, int d);[/QUOTE]
No, not really.
solved the problem. a guy helped me.
putting "inline before void.
[code]
class object
{
public:
float x;
float y;
float width;
float height;
inline void set_values(int,int,int,int);
};
inline void object::set_values(int a, int b, int c, int d)
{
x = a;
y = b;
width = c;
height = d;
}
[/code]
Making the function inline is just hiding the real problem.
[QUOTE=gparent;19896094]No, not really.[/QUOTE]
How does (int,int,int,int) make anysense? D:
[QUOTE=gparent;19896978]Making the function inline is just hiding the real problem.[/QUOTE]
that's true. I will take a look at this again.
[editline]07:29PM[/editline]
[QUOTE=Corewarp3;19898376]How does (int,int,int,int) make anysense? D:[/QUOTE]
I have no idea why. Try it and see yourself if it's working...
[QUOTE=Corewarp3;19898376]How does (int,int,int,int) make anysense? D:[/QUOTE]
How does it *not* make any sense?
A function declaration basically says "foo is a function that returns void and takes an int and a char as a parameter." The parameter names are irrelevant.
Take this, for example (excluding header guards):
foo.h:
[cpp]
void f(int);
[/cpp]
foo.c:
[cpp]
#include "foo.h"
void f(int i)
{
printf("%d", i);
}
[/cpp]
main.c:
[cpp]
#include "foo.h"
int main()
{
int i = 0;
f(i);
}
[/cpp]
What you seem to be forgetting is that C++ is compiled in more than 1 step. The compiler has a job to do, and then the linker has another job to do.
When the compiler works on main.c, it will first include "foo.h". foo.h says "there is a function called f that returns void and takes an integer as a parameter. That's all the compiler needs to know to make sure that the call in main is valid. It doesn't need to know any parameter names, it doesn't even need to know the code for foo. From main.c's "point of view", foo.c doesn't even exist.
Each file are compiled this way. So in our little example, we'd have two compilations: main.c, and foo.c. The compilation produces object files, which are not quite what we want as our end result.
That's where the linker comes in. The linker goes through every object file and sees an empty stub where f is called in main.o (the object file for main). When it produces the executable, it fills that 'gap' with f(int)'s definition (sorta, it basically adds a call to that function), acquired from foo.o (the object file for foo).
In the end, you have a complete program because the linker mixed and matched the different object files that were produced when the compiler compiled every file. But when the compiler compiles every single file one after the other, it knows very little about the rest of the functions and classes other than "they actually exist."
[QUOTE=Corewarp3;19898376]How does (int,int,int,int) make anysense? D:[/QUOTE]
It's actually quite handy when writing your classes, since you don't need to type out all the variable names again.
[QUOTE=likesoursugar;19898572]that's true. I will take a look at this again.[/QUOTE]
If inline fixed it then your include guards either don't work or you have a circular dependency.
[editline]03:24PM[/editline]
[QUOTE=Corewarp3;19898376]How does (int,int,int,int) make anysense? D:[/QUOTE]
Same way this makes sense (actually doesn't make sense, but works):
[cpp]
int foo(int a, int b, int c, int d);
int main()
{
foo(1, 2, 3, 4);
}
int foo(int cow, int sheep, int yourMom, int lol)
{
std::cout << cow << sheep << yourMom << lol;
}
[/cpp]
:v:
Sorry, you need to Log In to post a reply to this thread.