I have two files, main.ccp and namespace.cpp (Not the actual names, but for simplification)
My namespace.cpp can be boiled down to the following:
#pragma once
namespace MyNamespace {
int A = 0;
}
And my main.cpp basically just uses the content of MyNamespace:
#include "namespace.cpp"
int main() {
...
// Using MyNamespace::A
...
}
But I keep getting a LNK2005 error in MyNamespace.obj, that A is already defined in main.obj.
Which is weird: It's not like I've defined it twice. I'm literally just using it in my main file, but since I wanted to clean up my main file a little bit I put it into it's own file and into a namespace.
I don't understand where the problem is, would appreciate help.
Thanks
Related
I have been recently practicing managing multiple objects and drawing them in C++ using SFML library. I wanted my textures and future resources to be more reusable so I decided to make use of Thor library which suits my needs really well.
So I've written first few lines of code based on what you can find in this tutorial and the compiler always says:
main.cpp|12|error: 'textures_holder' does not name a type
This line gives an error :
textures_holder.acquire("Dirt", thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png"));
I'm using Code::Blocks IDE with MinGW compiler and SFML 2.5.0.
Here's my main.cpp and the header file which contains extern object :
//...
#include <Thor/Resources.hpp>
#include "Dirt_Block.h"
using namespace std;
//Adding textures to the texture library
//THIS LINE GIVES AN ERROR
textures_holder.acquire("Dirt", thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png"));
//Rest of code...
Dirt_Block.h (only the upper part) :
#ifndef DIRT_BLOCK_H
#define DIRT_BLOCK_H
#include <SFML\Graphics.hpp>
#include <vector>
#include <Thor/Resources.hpp>
#include <Thor/Resources/SfmlLoaders.hpp>
extern sf::Vector2u screenRes;
extern thor::ResourceHolder<sf::Texture, std::string> textures_holder;
//Rest of the code
I'd like to know what is causing this error and maybe help others who may experience similiar frustrating problems. Thanks for help.
EDIT :
As suggested in the comment I've declared a few extern int variables in the Dirt_Block.h so now it looks like this :
//...
extern int test_int_up;
extern sf::Vector2u screenRes;
extern thor::ResourceHolder<sf::Texture, std::string> textures_holder;
extern int test_int_d;
//...
And then assinged to them some value in main.cpp :
//...
test_int_up = 55;
test_int_d = 55;
//Adding textures to the texture library
textures_holder.acquire("Dirt", thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png"));
//...
But the compiler gives error :
main.cpp|9|error: 'test_int_up' does not name a type
main.cpp|10|error: 'test_int_d' does not name a type
main.cpp|12|error: 'textures_holder' does not name a type
Much less distracting to see what your problem is without all the extraneous code!
C++ programs don't start from the top of the file and run code down to the bottom. They start at the main(), and control flow proceeds from there, with one thing triggering another.
(Note: That doesn't take into account global constructor ordering, which does go in order of declaration--but you have no guarantee of the order declarations from "different files" might run in.)
Point being, you can't just make random function or method calls in the middle of a file. That's where you put declarations. You have to be inside of a function or method to make calls, e.g.
int main() {
textures_holder.acquire(
"Dirt",
thor::Resources::fromFile<sf::Texture>("Textures\\dirt_block.png")
);
...
}
I had a function to get points inside a 3D arc working inside a file but, trying to order the code into the appropriate folders, I broke it, and I don't know why because I think I am including it correctly.
Originally a lot of calculations were inside a file "messages.cpp", but it is supposed to have just the messages and the calculations should be in Calculations folder.
So now messages.cpp is something like this:
#include "../../FGProcessorModule/Calculations/ArcToPoints.h"
namespace myNamespace {
void MsgProvider::onEvent{
std::vector<Formulas::LLPoint> allPoints = ArcToPoints(center, start, end);
}
}
In "../../FGProcessorModule/Calculations/ArcToPoints.h" I have:
#ifndef ARCTOPOINTS_H
#define ARCTOPOINTS_H
#include blablabla
namespace myNamespace{
std::vector<Formulas::LLPoint> ArcToPoints (Formulas::LLPoint, Formulas::LLPoint, Formulas::LLPoint);
}
#endif /* ARCTOPOINTS_H */
And finally in "../../FGProcessorModule/Calculations/ArcToPoints.cpp" I have:
#include "ArcToPoints.h"
namespace myNamespace{
std::vector<Formulas::LLPoint> ArcToPoints (Formulas::LLPoint center, Formulas::LLPoint start, Formulas::LLPoint end){
//Lots of calculations
}
}
I think everything is OK but I receive this error when I want to compile:
undefined reference to `FVIS::ArcToPoints(Formulas::LLPoint,
Formulas::LLPoint, Formulas::LLPoint)'
I don't know if this will help others as it is a very specific problem, this is a project using ros and catkin.
I was missing including the new created file in CMakeLists.txt. Now it compiled just fine.
[EDIT:]
The problem seems to belong to the functions, that take default-parameters. Without separating in *.h *.cpp and main file it worked as i implemented something like:
void foo(double db;); // deklaration
void foo(double db = 4){ cout << db;} // definition
int main(){
foo(); // usage
return 1;
}
But if I separate deklaration (-> *.h), definition (-> *.cpp) and usage (-> main) compiling suddenly returns an erro telling, there is no function foo(void), as it does not recognize that there is a default parameter. Any suggestions for that?
[/EDIT]
I wrote a c++-program running somehow like:
#include <iostream>
/* other includes */
using namespace std;
class my_class
{
private:
/* variables */
public:
/* function deklarations (just some short ones are only defined not declared) */
};
ostream& operator<<(ostream &out, my_class member);
/* Definition of the member functions and of the not-member-function */
int main()
{
/*some trial codes of member-functions */
return 1;
}
In one total file all compiled well in Eclipse and worked. Now I also wanted to try seperate in a main,class-header and class-cpp file (called them "my_class.h" and my_class.cpp").
For that i put in class-header:
#ifndef MY_CLASS_H_
#define MY_CLASS_H_
#include <iostream>
/* other includes */
using namespace std;
class my_class
{
/* ... */
};
ostream & operator<<(ostream &out, my_class member);
#endif /* MY_CLASS_H_ */
I put in class-cpp:
/* Definition of the member functions and of the not-member-function */
I put in main:
#include <iostream>
#include "my_class.h"
#include "my_class.cpp"
int main()
{
/*some trial codes of member-functions */
return 1;
}
This version is compiling with the g++ command in commandline:
g++ -o main.exe main.cpp
But it does not Compile in Eclipse. There it gives me the Error:
...\my_class.cpp:11.1: error: 'my_class' does not name a type
and same for all other member functions and variables. I tried to follow the instructions from here (I put just "my_class.h" in main and my_class.cpp, but then it did not compile in Eclipse and in command line (of course then with the my_class.cpp included). Eclipse gives me an Error, that makes me believe Eclipse does not see the "my_class.cpp":
...\main.cpp:288:47: error: no matching function for call to 'my_class::foo(...)'
where foo stands for the first member-function declard in the "my_class.cpp" file. First It gave the error for the constructor too, but as I put it's definition directly into the *.h file it worked well. (That's why I think, it does not see the "my_class.cpp" file)
I think I might be missing something very trivial as I am very new to Eclipse, but I don't see it. I tried to make my questions and information as short as possible.
default-parameters need to be declared in the header-file as it contains the declarations and not in the cpp file, which contains the definitions. (An additional mistake was to declare them in the definition). Found some help here. But why did it work, as I implemented it in one whole file?
Answer:
If default-parameter is in the cpp-file, the main file does not see it as
it looks only into the header-file
But if the whole code is included in just one file, the default-value
can be found in the definition too.
To explain myself:
I considered answering my question, because it gives a better overview of the whole question and the question will now not appear as unanswered. After reading this, I think that it is the right way to do so.
I think I am having a similar problem to LNK2005, LNK1169 errors, "int __cdecl g(void)" (?g##YAHXZ) already defined but I cannot find the issue.
I am working with Visual Basic and I am having the following files
main.cpp
#include <iostream>
#include "functions.h"
using namespace std;
int main(){
number();
return 0;
}
I had a functions.cpp but after reading the question I linked before I renamed it for functions.h
int number(){
int i = 1;
return i;
}
Now it is displaying error LNK2005: "int __cdecl number(void)" (?number##YAHXZ) already defined in functions.obj
Is there anything wrong with the function number() in functions.h?
You are having linking issues.
Your immediate issue is that the functions.obj contains code that is being linked in. Then you redefine number() in main.cpp so they collide. Go ahead and clean the project (which should delete functions.obj, and you should be able to compile. I, however, recommend doing it this way.
functions.hpp (or functions.h)
int number();
functions.cpp
int number(){
int i = 1;
return i;
}
main.cpp
#include <iostream>
#include "functions.h"
using namespace std;
int main(){
number();
return 0;
}
When you compile, your program will create 2 objects with compiled code functions.obj, and main.obj. Since you use number in the main file, the compiler looks for the implementation of that function. Since the implementation of that function is in the functions.obj object, then you need to link that in.
If you are going to use number() across several C++ files, then you should always separate the code out into its own file and implementation.
functions.h should only declare the functio, as in
int number();
then functions.cpp should contain the function definition
int number(){
int i = 1;
return i;
}
Of course functions.cpp needs to be compiled (add it to the project).
The problem here is that you are including functions.h in multiple files. The issue could be avoided also by simply declaring the function static as in
static int number(){
int i = 1;
return i;
}
However, since it seems you are just learning, I would suggest you to study the basics of compiling c++ code.
In one of the modules you link in there is a function with the name number(). You define you own implementation so the linker does not know which one to use.
Either rename your function or use namespaces.
I am trying to relearn C++ after taking an intro course a few years ago and I’m having some basic problems. My current problem occurs when trying to use a friend function. Here is my code in 2 files.
First:
// fun.cpp
#include <iostream>
using namespace std;
class classA {
friend void funct();
public:
classA(int a=1,int b=2):propa(a),propb(b){cout<<"constructor\n";}
private:
int propa;
int propb;
void outfun(){
cout<<"propa="<<propa<<endl<<"propb="<<propb<<endl;
}
};
void funct(){ // ERROR HERE
cout<<"enter funct"<<endl;
classA tmp(1,2);
tmp.outfun();
cout<<"exit funct"<<endl;
}
Second:
// mainfile.cpp
#include <iostream>
#include "fun.cpp"
using namespace std;
int main(int nargin,char* varargin[]) {
cout<<"call funct"<<endl;
funct();
cout<<"exit main"<<endl;
return 0;
}
The error I am getting is "multiple definition of `funct()'". Am I using the wrong syntax when declaring it as a friend function?
Here is a highly simplified but hopefully relevant view of what happens when you build your code in C++.
C++ splits the load of generating machine executable code in following different phases -
Preprocessing - This is where any macros - #defines etc you might be using get expanded.
Compiling - Each cpp file along with all the #included files in that file directly or indirectly (together called a compilation unit) is converted into machine readable object code.
This is where C++ also checks that all functions defined (i.e. containing a body in { } e.g.
void Foo( int x){ return Boo(x); }) are referring to other functions in a valid manner.
The way it does that is by insisting that you provide at least a declaration of these other functions (e.g. void Boo(int); ) before you call it so it can check that you are calling it properly among other things. This can be done either directly in the cpp file where it is called or usually in an included header file.
Note that only the machine code that corresponds to functions defined in this cpp and included files gets built as the object (binary) version of this compilation unit (e.g. Foo) and not the ones that are merely declared (e.g. Boo).
Linking - This is the stage where C++ goes hunting for stuff declared and called in each compilation unit and links it to the places where it is getting called. Now if there was no definition found of this function the linker gives up and errors out. Similarly if it finds multiple definitions of the same function signature (essentially the name and parameter types it takes) it also errors out as it considers it ambiguous and doesn't want to pick one arbitrarily.
The latter is what is happening in your case. By doing a #include of the fun.cpp file, both fun.cpp and mainfile.cpp have a definition of funct() and the linker doesn't know which one to use in your program and is complaining about it.
The fix as Vaughn mentioned above is to not include the cpp file with the definition of funct() in mainfile.cpp and instead move the declaration of funct() in a separate header file and include that in mainline.cpp. This way the compiler will get the declaration of funct() to work with and the linker would get just one definition of funct() from fun.cpp and will use it with confidence.
The problem is that if you include fun.cpp in two places in your program, you will end up defining it twice, which isn't valid.
You don't want to include cpp files. You want to include header files.
The header file should just have the class definition. The corresponding cpp file, which you will compile separately, will have the function definition.
fun.hpp:
#include <iostream>
class classA {
friend void funct();
public:
classA(int a=1,int b=2):propa(a),propb(b){std::cout<<"constructor\n";}
private:
int propa;
int propb;
void outfun(){
std::cout<<"propa="<<propa<<endl<<"propb="<<propb<< std::endl;
}
};
fun.cpp:
#include "fun.hpp"
using namespace std;
void funct(){
cout<<"enter funct"<<endl;
classA tmp(1,2);
tmp.outfun();
cout<<"exit funct"<<endl;
}
mainfile.cpp:
#include <iostream>
#include "fun.hpp"
using namespace std;
int main(int nargin,char* varargin[]) {
cout<<"call funct"<<endl;
funct();
cout<<"exit main"<<endl;
return 0;
}
Note that it is generally recommended to avoid using namespace std in header files.
This problem happens because you are calling fun.cpp instead of fun.hpp. So c++ compiler finds func.cpp definition twice and throws this error.
Change line 3 of your main.cpp file, from #include "fun.cpp" to #include "fun.hpp" .
You have #include "fun.cpp" in mainfile.cpp so compiling with:
g++ -o hw1 mainfile.cpp
will work, however if you compile by linking these together like
g++ -g -std=c++11 -Wall -pedantic -c -o fun.o fun.cpp
g++ -g -std=c++11 -Wall -pedantic -c -o mainfile.o mainfile.cpp
As they mention above, adding #include "fun.hpp" will need to be done or it won't work. However, your case with the funct() function is slightly different than my problem.
I had this issue when doing a HW assignment and the autograder compiled by the lower bash recipe, yet locally it worked using the upper bash.