This question already has answers here:
Why should I not include cpp files and instead use a header?
(14 answers)
Closed 2 years ago.
Having 2 simple files like that:
Main.c:
#include "Initialization.cpp"
int main() {
return 0;
}
and Initialization.cpp:
int main2() {
return 0;
}
I'm getting en error:
..."int __cdecl main2(void)" (?main2##YAHXZ) already defined in Initialization.obj...
What's peculiar when i complied the program the first time everything was ok. After recompilation this error starts appearing.
PS. I'm using Visual Studio c++ 2019
The preprocessor copies everything in the include file into Main.c which will look
int main2() {
return 0;
}
int main() {
return 0;
}
Both Initialization.o and Main.o now have definition for
main2(). Thus, you break the one definition rule and invoke undefined behavior.
I have a se of embedded C for a TI processor that need to be unit tested.
For target compilation IAR is used but i am running the tests on a Win7 machine using MinGW GCC.
In the C code there are functions containing state machines that sometimes need to be reset between tests. These state machines often keep their state variable locally static, making that task difficult if not impossible.
I'm not very C++ class savvy but i had an idea about "importing" the C functions into a wrapping C++ class as memberfunctions making it possible to just create a new object whenever a reset i needed. The code below is non functional but it illustrates my idea.
in main.cpp:
#include "statemachine.h"
using namespace std;
class stateMachineWrapper {
public:
extern void stateMachine(void);
};
int main() {
stateMachineWrapper myObject;
myObject.stateMachine();
myObject.stateMachine();
stateMachineWrapper myNewObject;
myNewObject.stateMachine();
myNewObject.stateMachine();
return 0;
}
in statemachine.h:
void stateMachine(void);
in statemachine.c:
#include <stdio.h>
void stateMachine(void)
{
static int myState = 0;
switch(myState)
{
case 0:
{
printf("Init State");
myState = 1;
break;
}
case 1:
{
printf("Second state");
break;
}
default:
{
printf("Default");
break;
}
}
}
Alterations to the statemachine.c/.h is not encouraged since it can be considered "legacy".
Any other solutions is of course welcome as well!
The wrapping won't help. The C++ code has no way of reaching the internal static variable inside the state machine written in C.
One solution is to use dynamic code loading for the C parts, that will make the early initialization code and clear the static variable.
You could also split the tests into multiple executables, that has the same effect but probably larger overhead (=tests will run more slowly).
#unwind sent me looking at dynamic code loading!
Reading these:
Dynamically load a function from a DLL and http://www.transmissionzero.co.uk/computing/building-dlls-with-mingw/ gave me enough to concoct the following solution.
in statemachine.h:
void stateMachine(void);
in statemachine.c:
#include <stdio.h>
void stateMachine(void)
{
static int myState = 0;
switch(myState)
{
case 0:
{
printf("Init State");
myState = 1;
break;
}
case 1:
{
printf("Second state");
break;
}
default:
{
printf("Default");
break;
}
}
}
in statemachinelib.c:
#include "statemachine.h"
__declspec(dllexport) void __cdecl statemachineWrap()
{
stateMachine();
}
in main.c:
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
typedef int (__stdcall *f_funci)();
int main(int argc, char **argv)
{
HINSTANCE hGetProcIDDLL = LoadLibrary("statemachinelib.dll");
f_funci funci = (f_funci)GetProcAddress(hGetProcIDDLL, "statemachineWrap");
funci();
funci();
funci();
FreeLibrary(hGetProcIDDLL); //Windows detects that no one is using this library anymore and unloads it from memory, giving the new LoadLibrary a fresh instance
hGetProcIDDLL = LoadLibrary("statemachinelib.dll");
funci = (f_funci)GetProcAddress(hGetProcIDDLL, "statemachineWrap");
funci();
funci();
funci();
return 0;
}
In this code i have omitted a lot of safety statements such as checking if the DLL could be loaded, if the function is found, whether we want too dllexport or dllimport and so on only to make it easier to grasp what is going on. If you are going to implement this in any real project you should at least read both of the resources i mentioned above.
compilation of the DLL using MinGW:
>gcc -c statemachine.c statemachinelib.c
>gcc -o statemachinelib.dll -s -shared statemachinelib.o statemachine.o -Wl,--subsystem,windows
compilation of the executable, also MinGW:
>gcc -o main.exe main.c
execution yields:
>main.exe
Init State
Second state
Second state
Init State
Second state
Second state
I'll just leave this here for a few days and if no one objects i will mark this as my accepted answer!
Edit: I have elaborated a bit and there's another (solved) question from me here with just a slight tweak Exporting a function, cast into a pointer through a DLL
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I am experiencing something weird with my c++ source file or perhaps the compiler itself. It seems that when I attempt to compile the file, it hits me with a message -
undefined reference to "Basic_int_stack::Basic_int_stack()
undefined reference to "Basic_int_stack::Push(int)
Here is my code (I'm still a beginner so don't expect any crazy professional code )
Header file:
class Basic_int_stack
{
public:
// This part should be implementation independent.
Basic_int_stack(); // constructor
void push( int item );
int pop();
int top();
int size();
bool empty();
private:
// This part is implementation-dependant.
static const int capacity = 10 ; // the array size
int A[capacity] ; // the array.
int top_index ; // this will index the top of the stack in the array
};
Implementations:
#include "basic_int_stack.h"// contains the declarations of the variables and functions.
Basic_int_stack::Basic_int_stack(){
// the default constructor intitializes the private variables.
top_index = -1; // top_index == -1 indicates the stack is empty.
}
void Basic_int_stack::push( int item ){
top_index = top_index + 1;
A[top_index] = item ;
}
int Basic_int_stack::top(){
return A[top_index];
}
int Basic_int_stack::pop(){
top_index = top_index - 1 ;
return A[ top_index + 1 ];
}
bool Basic_int_stack::empty(){
return top_index == -1 ;
}
int Basic_int_stack::size(){
return top_index;
}
Main Function:
#include "basic_int_stack.h"
#include <iostream>
int main()
{
int var;
Basic_int_stack s1;
while((std::cin >> var)>=0){
s1.push(var);
}
return 0;
}
This is happening because you're building your main file without building and linking your class implementation file as well. You need to adjust your build settings somehow.
It is because you don't include Basic_int_stack.cpp when you complile.
Simplely speaking, when you encounter Undefined reference to xxx, it is a error generated by linker, when means the compliler can't find the implements. So you need check if you include the cpp file or dynamic library or static library.
I faced the same problem. Finally I found a fix by including .cpp file in the main file.
#include "file_name.cpp" //In the main file
This question already has answers here:
One or more multiply defined symbols found
(9 answers)
Closed 8 years ago.
I have a main.cpp file which contains the following:
#include<iostream>
using namespace std;
#include"Command.cpp"
#define EXIT 5
int main(){
int code;
do{
code = getCommand();
doCommand(code);
}while(code != EXIT);
}
and in my Command.cpp file, I have some functions:
#include<iostream>
using namespace std;
#include"Service.h"
Service * first = new Service();
int getCommand(){
cout<<"Choose one of the following commands: "<<endl;
cout<<"1. Add new service"<<endl;
cout<<"2. Add new subservice"<<endl;
cout<<"3. Add parent to a service"<<endl;
cout<<"4. Delete a service(and it's subservices)"<<endl;
cout<<"Your Choice: ";
int c;
cin>>c;
return c;
}
void addService(){
first->add();
}
void addSubService(){
cout<<"Let's choose the parent first: "<<endl;
int * one = new int;
*one = 1;
first->print(one,0);
cout<<"0. here."<<endl<<"> ";
int id;
cin>>id;
Service * f = first->find(one,id);
}
void addParentToService(){
}
void doCommand(int c){
switch(c){
case 1:
addService();
break;
case 2:
addSubService();
break;
case 3:
addParentToService();
break;
case 4:
//deleteService();
break;
}
}
But when I hit the compile button in Visual Studio, I get the following error:
1>Command.obj : error LNK2005: "void __cdecl addParentToService(void)" (?addParentToService##YAXXZ) already defined in Source.obj
1>Command.obj : error LNK2005: "void __cdecl addService(void)" (?addService##YAXXZ) already defined in Source.obj
1>Command.obj : error LNK2005: "void __cdecl addSubService(void)" (?addSubService##YAXXZ) already defined in Source.obj
...
I believe the problem is in the linking of these files but I don't know what to do...
You should never include cpp files into other cpp files. This is where using a .h file comes in. You can refer to this SO question on how to do that:
Using multiple .cpp files in c++ program?
Essentially, the problem you are encountering is that you are including your Command.cpp file multiple times. The preprocessor takes a the contents of a file, and directly copies it into the file it is included in, and that means that you might end up having multiple definitions of the same object if your files are not guarded from being re included. (This is also where include guards come into play).
This is an overall large topic to cover, and there are many resources that talk about this.
When you want to link functions across different files, you should never include .cpp files within another .cpp file. You only include .hh files, where you define any other functions, which are implemented across other .cpp files.
Example: main.cpp
#include "42.hh"
#include <iostream>
int main() {
func42();
return 0;
}
Include file: 42.hh
#ifndef _42_HH_
#define _42_HH_
void func42();
#endif
Function file: 42.cpp
#include <iostream>
void func42() {
std::cout << "Fourty-two" << std::endl;
}
Compile and run:
~$ g++ 42.cpp main.cpp -o fourty-two
~$ ./fourty-two
Fourty-two
I've got the following functions declared in creature.h (under public):
void _hop();
void _turn(size_t way);
void _infect();
Point _facing();
bool _isEmpty();
bool _wall();
bool _same();
Then their implementation in the .cc (I've deleted a bunch of code for shortness):
void Creature::_hop(){
CODE
}
Point Creature::_facing(){
CODE
}
void Creature::_infect(){
CODE
}
bool Creature::_isEmpty(){
CODE
}
bool Creature::_wall(){
CODE
}
bool Creature::_same(){
CODE
}
But then upon compile I get these errors:
creature.cc:25: error: no 'void Creature::_hop()' member function declared in class 'Creature'
creature.cc:54: error: no 'void Creature::_turn(size_t)' member function declared in class 'Creature'
creature.cc:88: error: no 'geometry::Point Creature::_facing()' member function declared in class 'Creature'
creature.cc:105: error: no 'void Creature::_infect()' member function declared in class 'Creature'
creature.cc:114: error: no 'bool Creature::_isEmpty()' member function declared in class 'Creature'
creature.cc:121: error: no 'bool Creature::_wall()' member function declared in class 'Creature'
creature.cc:127: error: no 'bool Creature::_same()' member function declared in class 'Creature'
tons of other functions are getting read fine but these ones aren't getting any love. ?????
EDIT:
Not sure about the down votes, probably because you guys are assuming that I didn't either a) include it in the creature class or b) #include "creature.h". I did both, just didn't include that in the question since I thought that was obvious.
EDIT 2: You want .cc and .h? Oh dear lord.
CREATURE.H:
#ifndef CREATURE
#define CREATURE
class Creature {
public:
// Constructor (note there is no need for a destructor.)
Creature();
Creature(Species *species,World *world,Point pt,Direction d);
// takeOneTurn executes lines of this creature's species program,
// beginning on programLine and continuing until a HOP, LEFT, RIGHT, or
// INFECT is executed.
void takeOneTurn();
// getters and setters do the obvious things.
Species *getSpecies();
Direction getDirection();
// use this to initialize and infect. It also sets programLine to 1.
void setSpecies(Species * s);
void _hop();
void _turn(size_t way);
void _infect();
Point _facing();
bool _isEmpty();
bool _wall();
bool _same();
private:
Species *species; // pointer to this creature's species
World *world; // a pointer to the world in which this
// creature is located.
Point loc; // where in the world this creature is located
Direction dir; // current direction this creature is facing
size_t programLine; // current program line
};
#endif
CREATURE.CC
#include "creature.h"
#include <cstdlib>
Creature::Creature(Species *s, World *w,Point pt,Direction d){
world = w;
species = s;
loc = pt;
dir = d;
programLine = 0;
}
Species* Creature::getSpecies(){
return species;
}
Direction Creature::getDirection(){
return dir;
}
void Creature::setSpecies(Species* s){
species = s;
}
void Creature::_hop(){
switch(dir){
case NORTH:
if(!world->getContents(Point(loc.col,loc.row+1))){
world->setContents(loc, NULL);
world->setContents(Point(loc.col,loc.row+1), this);
}
break;
case SOUTH:
if(!world->getContents(Point(loc.col,loc.row-1))){
world->setContents(loc, NULL);
world->setContents(Point(loc.col,loc.row-1), this);
}
break;
case EAST:
if(!world->getContents(Point(loc.col+1,loc.row))){
world->setContents(loc, NULL);
world->setContents(Point(loc.col+1,loc.row), this);
}
break;
case WEST:
if(!world->getContents(Point(loc.col-1,loc.row))){
world->setContents(loc, NULL);
world->setContents(Point(loc.col-1,loc.row), this);
}
break;
}
}
void Creature::_turn(size_t way){
if(way == 0){
switch(dir){
case NORTH:
dir = WEST;
return;
case WEST:
dir = SOUTH;
return;
case SOUTH:
dir = EAST;
return;
case EAST:
dir = NORTH;
return;
}
} else {
switch(dir){
case NORTH:
dir = EAST;
return;
case WEST:
dir = NORTH;
return;
case SOUTH:
dir = WEST;
return;
case EAST:
dir = SOUTH;
return;
}
}
}
Point Creature::_facing(){
switch(dir){
case NORTH:
return Point(loc.col,loc.row+1);
break;
case WEST:
return Point(loc.col-1,loc.row);
break;
case SOUTH:
return Point(loc.col,loc.row-1);
break;
case EAST:
return Point(loc.col+1,loc.row);
break;
}
}
void Creature::_infect(){
Point facing = _facing();
if(!world->inRange(facing))return;
Creature* enemy = world->getContents(facing);
if(!enemy) return;
enemy->setSpecies(species);
world->setContents(facing, enemy);
}
bool Creature::_isEmpty(){
Point facing = _facing();
if(!world->inRange(facing))return false;
if(!world->getContents(facing)) return true;
return false;
}
bool Creature::_wall(){
Point facing = _facing();
if(!world->inRange(facing))return true;
return false;
}
bool Creature::_same(){
Point facing = _facing();
if(!world->inRange(facing))return true;
if(!world->getContents(facing)) return false;
Creature* enemy = world->getContents(facing);
return (enemy->species == species);
}
bool _random(){
int k = random();
return (k%2);
}
void Creature::takeOneTurn(){
Instruction whatToDo = species->programStep(programLine);
switch(whatToDo.op){
case HOP:
_hop();
programLine++;
break;
case LEFT:
_turn(0);
programLine++;
break;
case RIGHT:
_turn(1);
programLine++;
break;
case INFECT:
_infect();
programLine++;
break;
case IFEMPTY:
if(_isEmpty()){
programLine = whatToDo.line;
takeOneTurn();
}
break;
case IFWALL:
if(_wall()){
programLine = whatToDo.line;
takeOneTurn();
}
break;
case IFSAME:
if(_same()){
programLine = whatToDo.line;
takeOneTurn();
}
break;
case GO:
programLine = whatToDo.line;
takeOneTurn();
break;
case IFRANDOM:
if(_random()) programLine = whatToDo.line;
else programLine++;
takeOneTurn();
break;
}
}
Phew!
What you have described should work fine, so we have to assume that your description doesn't quite match reality.
Specifically, the following code compiles and runs fine.
pax$ cat creature.h
class Creature {
public:
void _hop();
};
pax$ cat creature.cc
#include <iostream>
#include "creature.h"
void Creature::_hop() {
std::cout << "Hop\n";
}
int main (void) {
Creature c;
c._hop();
return 0;
}
pax$ rm creature ; g++ -o creature creature.cc ; ./creature
Hop
Since that transcript shows what you seem to be doing, my advice is to post your actual code for analysis, including the full header file and almost full source file (you can leave in the CODE markers since they won't affect this particular problem but it would be useful to see things like the include statements and so forth).
The best problem reports should come with:
the expected behaviour.
the actual behaviour.
a small complete program that exhibits the errant behaviour.
Based on your code updates (and assuming they're complete), you have the problem that size_t, Species, World, Point and Direction are not actually defined before you include creature.h in your creature.cc file.
This is causing the creation of the Creature class to fail on the second constructor so that it doesn't know about that class. Then, when you try to define the actual code for said class, the compiler (rightly) complains that it doesn't exist.
When I add a very small main to your code and try to compile, I get these header file problems:
In file included from creature.cc:1:
creature.h:5: error: expected `)' before '*' token
creature.h:13: error: ISO C++ forbids declaration of 'Species' with no type
creature.h:13: error: expected ';' before '*' token
creature.h:14: error: 'Direction' does not name a type
creature.h:16: error: 'Species' has not been declared
creature.h:18: error: 'size_t' has not been declared
creature.h:20: error: 'Point' does not name a type
creature.h:26: error: ISO C++ forbids declaration of 'Species' with no type
creature.h:26: error: expected ';' before '*' token
creature.h:27: error: ISO C++ forbids declaration of 'World' with no type
creature.h:27: error: expected ';' before '*' token
creature.h:29: error: 'Point' does not name a type
creature.h:30: error: 'Direction' does not name a type
creature.h:31: error: 'size_t' does not name a type
which are caused by those non-definitions.
Then I see the sort of errors you describe, such as:
creature.cc:129: error: 'world' was not declared in this scope
creature.cc:129: error: 'facing' was not declared in this scope
creature.cc:130: error: 'world' was not declared in this scope
creature.cc:130: error: 'facing' was not declared in this scope
creature.cc:131: error: 'world' was not declared in this scope
creature.cc:131: error: 'facing' was not declared in this scope
creature.cc:132: error: 'class Creature' has no member named 'species'
creature.cc:132: error: 'species' was not declared in this scope
(just a sample of the many pages of output).
You need to ensure that you have included the header files which define those types before including creature.h. Ideally, creature.h would do this itself rather than relying on whatever is using it to do it.
size_t can be found in <cstring>, the others need to be found by yourself. For example, placing:
#include <cstring>
typedef int Species;
typedef int World;
typedef int Point;
typedef int Direction;
at the top of your header file gets rid of all those errors - it introduces a bucketload of other errors since the typedef statements are wrong but I'm just illustrating what you need to do here.
Find out where those other things are defined and include them, along with <cstring>, at the top of creature.h.
It looks like you're trying to write a class. You have to put the function declarations in a class declaration, then include the header in the source file.
Creature.h
class Creature {
private: // assuming these are private functions
void _hop();
void _turn(size_t way);
void _infect();
Point _facing();
bool _isEmpty();
bool _wall();
bool _same();
}; // don't forget the ;
Creature.cc
#include "Creature.h"
... your original Creature.cc contents ...
If you're not writing a class but a series of free functions, remove the Creature:: from your function names in Creature.cc.
Your header file says that the functions are standalone, but your source file says they belong to the "Creature" class. At the very minimum, you need to either:
surround your declarations with a struct or class
struct Creature
{
....your function declarations...
};
or
Remove the Creature:: from your cpp file.
Finally, starting function names with an undescore is bad practice. Don't do it.
Just before
class Creature {
try adding the following:
#error The class declaration for Creature is indeed being compiled
And see if that generates an error. If not, then I suspect something went wrong with your header guard.
Your header guard macro name should be longer than just CREATURE. It's too easy for a CREATURE macro to be accidentally defined somewhere else (like in a library) and messing up your header guard. If the name of your project is, say, "Monster Mash", then your header guard for creature.h should be something complicated like: MONSTER_MASH_CREATURE_H or MONSTER_MASH_CREATURE_INCLUDE. That way, it's extremely improbable that someone else has already defined your header guard macro.
Move #include "creature.h" to the TOP of the list of includes in your creature.cc file. Then, fix the compile errors (types 'Point', etc. not defined), and try again. The creature.h file needs to include or forward-declare all the types it uses, or you get weird problems.
I also second the suggestion to put a #error just above the Creature class declaration, to ensure that CREATURE didn't somehow get defined elsewhere (and thus force the class declaration to be skipped). And you might want a more unique header on your header file -- my own convention would have been _CREATURE_H_
Anyway, the upshot is that most of these kinds of bugs are caused by problems somewhere else, and the symptoms are only distantly related to the reason. C++, alas, is loaded with these kinds of gotchas.