can not find bug in the code vector usage - c++

I can't find bug in this code
In function `BinaryCode::decode(std::string)':
undefined reference to `BinaryCode::m_vecStr'
undefined reference to `BinaryCode::m_vecStr'
undefined reference to `BinaryCode::m_vecStr'
undefined reference to `BinaryCode::m_vecStr'
undefined reference to `BinaryCode::m_vecStr'
more undefined references to `BinaryCode::m_vecStr' follow
http://codepad.org/PtZkGx6W
output is in above site:
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
using namespace std;
class BinaryCode{
public:
BinaryCode(void);
~BinaryCode(void);
static vector<string> m_vecStr;
vector<string> decode(string message);
};
BinaryCode::BinaryCode(void){
}
BinaryCode::~BinaryCode(void){
}
vector<string> BinaryCode::decode(string message){
m_vecStr.clear();
char szNone[]={"NONE"};
m_vecStr.push_back(szNone);
m_vecStr.push_back(message);
return m_vecStr;
}
int main(){
BinaryCode bc;
//cout<<bc.decode("12310122");
return 0;
}

You must define the static member outside of the class declaration. Try adding this after the class declaration:
vector<string> BinaryCode::m_vecStr;
If you're declaring your class in a distinct file, make sure you define the static members in the implementation file (generally .cpp), not in the header file (.h).

It is not a bug it is a linker error which tells you that linker cannot find definition for m_vecStr.
You need to define a static variable, in your code you just declared it but forgot to define it.
Add the following definition:
vector<string> BinaryCode::m_vecStr;
only once in your source file.

Related

Forward declaration is not working as expected

I'm defining a class SpatialCriterionCallback in a header file "spatialcriterion.h" like this:
#include "ros/ros.h"
#include "neuromorphic_stereo/MatchingCandidates.h"
#include <vector>
class SpatialCriterionCallback
{
public:
// constructors & destructors
SpatialCriterionCallback()=default;
SpatialCriterionCallback(ros::NodeHandle);
~SpatialCriterionCallback()=default;
private:
std::vector<neuromorphic_stereo::MatchingCandidates> matching_candidates;
void subscriberCallbackFunction(constneuromorphic_stereo::MatchingCandidates&);
}
Then in the file "spatialcriterion.cpp" I'm defining a constructor that invokes a ros::SubscriberNode like this:
#include "spatialcriterioncallback.h"
SpatialCriterionCallback::SpatialCriterionCallback(ros::NodeHandle n)
{
this->n =n;
this->time_criterion_topic_handle = this->n.subscribe("TimeCriterionTopic",
1e4,
&SpatialCriterionCallback::subscriberCallbackFunction,
this);
}
When I try compiling this within a qtcreator project, the compiler tells me
error: undefined reference to
`SpatialCriterionCallback::subscriberCallbackFunction(neuromorphic_stereo::MatchingCandidates_ const&)'
When I add the following lines to my "spatialcriterion.cpp" file it will compile just fine:
void SpatialCriterionCallback::subscriberCallbackFunction(const neuromorphic_stereo::MatchingCandidates & msg){
this->matching_candidates.push_back(msg);
}
Now my question is: Shouldn't this code compile without the function definition, because the function subscriberCallbackFunction() has already been declared in "spatialcriterion.h"? Why is it necessary for the compiler to have the function defined?
I also tried finding an explanation to this behaviour here, but all the other posts about failing forward declaration (like this or this) aren't exactly what I'm looking for.
Even if you declared the method in your class, it doesn't exist.
When you reference that function in the constructor, the linker tells you that it needs to know where the method is.
The code compiles fine, it doesn't link.

How is it possible that I can make an instance from a class in which some member methods aren't defined yet? (C++)

I'm comparatively new to C++ so I tested some things out in Xcode, and found a really weird thing.
This is my 'Testing.h' file
#ifndef Testing_h
#define Testing_h
class Testing{
private:
int a;
public:
Testing(int a=3);
void hey(int b);
};
#endif
This is my 'Testing.cpp' file
#include "Testing.h"
Testing::Testing(int a){
a = 4;
}
And finally, this is the 'main.cpp' file
#include <iostream>
#include "Testing.h"
using namespace std;
int main(){
Testing a;
//Apparently not completing the definitions of every abstract methods in the class is not a problem
}
I only declared 'void hey(int b)' in 'Testing.h' but have not defined it in 'Testing.cpp'. So I was wondering how it is possible for the compiler to successfully compile the 'main.cpp' without having enough information of 'void hey(int b)'. Thanks in advance!
Because you never require there to be a definition for hey().
You can require a definition by calling it, for example :
a.hey(42);
And you'll see that the linker isn't too happy because hey is an undefined reference.
Testing a;//Apparently not completing the definitions of every abstract methods in the class is not a problem
You defined constructor with default value a=3 but calling both constructor argument and class parameter the same name is bad practice.
Instead you can write this:
//Testing.h
#ifndef Testing_h
#define Testing_h
using namespace std;
class Testing{
private:
int number;
public:
Testing(int a=3): number(a = 4){}//it's the same as your implementation in cpp file
void hey(int b);
int getNumber() {return number;}
};
#endif
//main.cpp
#include <iostream>
#include "Testing.h"
int main()
{
Testing object;
cout<<object.getNumber();// returns 4
return 0;
}
And why hey compiles?
During building your project compiler translates your source code into object code by verifying the syntax. After that process linker checks the definitions marked by whole phrases. Source code is compiled from each file provided. Linker doesn't care for the implementation presence, it only looks it up if a method is used by the program. So even without implementation of hey your program compiles.
Last remark
It's discouraged to include .cpp files use headers instead. Sometimes you can get yourself into multiple definitions of the same functions causing compiler errors.

c++ calling a class within a class

So i had the following code which ran perfectly.
Here "rngSource" makes an instance of the class contained in rand.h. rng.rFloat64() calls random numbers between 0 and 1.
main.cpp
#include "rand.h" // rngSource
rngSource rng;
class particle{
public:
double r[nd], v[nd];
particle()
{
for (int i=0; i<nd; ++i)
{
r[i]=L*rng.rFloat64();
v[i]=rng.rFloat64();
}
}
};
But when I tried to separate the class implementation from main.cpp into particle.h and particle.cpp, as indicated below:
particle.h
#ifndef particle_H
#define particle_H
class particle{
public:
double r[2], v[2];
particle();
};
#endif
particle.cpp
#include "rand.h" // rngSource
#include "particle.h"
particle::particle()
{
double ran = (double) rand()/(double)RAND_MAX;
static const double L=10;
for (int i=0; i<2; ++i)
{
r[i]=L*ran;
v[i]=ran;
}
}
While the new main.cpp looks like this:
#include "rand.h" /* rngSource() */
#include "particle.h" /* particle class */
rngSource rng;
int main(){
rng.rseed(getpid()*time(NULL));
particle p[N];
....
}
But when i try to compile i get the following errors:
particle.cpp: In constructor ‘particle::particle()’:
particle.cpp:20:17: error: ‘rng’ was not declared in this scope
r[i]=L*rng.rFloat64(); //ran;
^
particle.o:(.data+0x0): multiple definition of `rng_cooked'
new.o:(.data+0x0): first defined here
particle.o:(.data+0x1300): multiple definition of `kn'
new.o:(.data+0x1300): first defined here
particle.o:(.data+0x1500): multiple definition of `wn'
new.o:(.data+0x1500): first defined here
particle.o:(.data+0x1700): multiple definition of `fn'
new.o:(.data+0x1700): first defined here
new.cpp:(.text+0x1fb1): undefined reference to `rngSource::rseed(long long)'
particle.o: In function `particle::particle()':
particle.cpp:(.text+0x1fa2): undefined reference to `rngSource::rseed(long long)'
particle.cpp:(.text+0x1fb5): undefined reference to `rngSource::rFloat64()'
particle.cpp:(.text+0x1fda): undefined reference to `rngSource::rFloat64()'
collect2: error: ld returned 1 exit status
Would anyone here happen to know how to fix this?
thank you.
Three problems.
Problem 1:
particle.cpp: In constructor ‘particle::particle()’:
particle.cpp:20:17: error: ‘rng’ was not declared in this scope
r[i]=L*rng.rFloat64(); //ran;
The ultra cheesy answer is to add extern rngSource rng; to particle.cpp above the particle constructor. extern means this variable exists, but its storage is allocated elsewhere. The linker will track it down for you. This is quick, dirty, and will get you back on the road with minimal code changes.
Better solutions are to add extern rngSource rng; to rand.h and then define rngSource rng; in rand.cpp for all users or placing extern rngSource rng; in a brand new main.h and include main.h in particle and other modules called by main.
The best solution is probably to create a bool init(rngSource & rng) function in particle and do grunt work the constructor's currently doing. That way if rng doesn't exist, the compiler catches it when you try to call init.
particle p[N];
for (size_t index; index < N; index++)
{
p[index].init(rng);
}
Problem 2
particle.o:(.data+0x0): multiple definition of `rng_cooked'
new.o:(.data+0x0): first defined here
particle.o:(.data+0x1300): multiple definition of `kn'
new.o:(.data+0x1300): first defined here
particle.o:(.data+0x1500): multiple definition of `wn'
new.o:(.data+0x1500): first defined here
particle.o:(.data+0x1700): multiple definition of `fn'
new.o:(.data+0x1700): first defined here
rng_cooked, kn, wn, and fn are almost certainly being defined in rand.h. This means everyone who includes rand.h tries to create their own version of those variables resulting in collisions when the linker tries to line up names with storage locations.
Solution is similar to the first problem: Add extern to the variable definitions in the rand.h and define them in rand.cpp.
Problem 3
new.cpp:(.text+0x1fb1): undefined reference to `rngSource::rseed(long long)'
particle.o: In function `particle::particle()':
particle.cpp:(.text+0x1fa2): undefined reference to `rngSource::rseed(long long)'
particle.cpp:(.text+0x1fb5): undefined reference to `rngSource::rFloat64()'
particle.cpp:(.text+0x1fda): undefined reference to `rngSource::rFloat64()'
No idea. Are you certain you are passing rand.cpp to gcc?

Function prototype thinks a class type is undefined, although it's defined in the same header file

It seems that the IF_ID_WRITE class object that is declared in main and defined in a header file is not recognized by a function prototype in the same header file. When I move the prototype from Pipeline.h to Project.cpp, it compiles fine, but I don't want to resort to doing that.
What do I need to change to make it recognize the object type from Pipeline.h?
When I compile, I get the following three errors:
error C2065: 'IF_ID_WRITE' : undeclared identifier
error C2065: 'aIF_ID_WRITE' : undeclared identifier
error C2182: 'IF_stage' : illegal use of type 'void'
Pipeline.h file contains
#include <cstdlib>
#include <iomanip>
#include <iostream>
using namespace std;
#pragma once
//function prototypes
void IF_stage(IF_ID_WRITE &aIF_ID_WRITE);
//IF_ID_WRITE defined
class IF_ID_WRITE {
private:
int inst;
int writeRegNum;
int readReg1Num;
int readReg2Num;
int offset;
int incrPC;
public:
IF_ID_WRITE();
void setWriteRegNum(int);
void setReadReg1Num(int);
void setReadReg2Num(int);
~IF_ID_WRITE()
};
Project.cpp contains
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include "Pipeline.h"
using namespace std;
#pragma once
int main(){
.
.
.
IF_ID_WRITE aIF_ID_WRITE; //creating an object called aIF_ID_WRITE of type IF_ID_WRITE
IF_stage(aIF_ID_WRITE); //a function that will pass the object by reference
In the Pipeline.cpp file:
void IF_stage(IF_ID_WRITE& aIF_ID_WRITE)
{
//code
}
edited to show IF_ID_WRITE being defined in Pipeline.cpp
C++ is a top-down language, the type needs to be declared before you can declare a function that uses it. The compiler won't look-ahead to try to figure out whether IF_ID_WRITE exists later in the translation unit, it will just fail as it does not exist before the function declaration.
If you reorder the definition of the IF_ID_WRITE type and the function it should work. Since you are only declaring the function in the header, you can also provide a declaration of the type (no definition required) before the function declaration:
class IF_ID_WRITE;
void IF_stage(IF_ID_WRITE& aIF_ID_WRITE);
[There are other syntax issues, like the destructor missing (), but I assume this is an issue with the copy-paste into the question. I don't really believe this, but I'll skip the full code review]

function in main program OK, undefined references otherwise

I have a function, that when defined in the main file of my program, works as I wish, and produces a lot of undefined references, when defined in a header file.
This header file exists:
#include "Domain.h"
#include "Character.h"
class Item {
public:
Character input;
Item(Character c2);
};
Item pistol(int which, float strength);
The function that makes problems is pistol. It looks like
Item pistol(int which, float strength) {
Interval i = Interval(0, 1);
Domain d = Domain(i);
Character c = Character({d}, {1});
return Item(c);
}
When I try to link the code with my main program, all calls that refer to object in Domain.h and Character.h are undefined references, that means I get linking time errors like:
undefined reference to `Character::show()'
...
undefined reference to `Interval::Interval(float, float)'
...
these errors are at places in the code, which are not inside the pistol function.
When I move this function to my main program, everything works as expected:
#include "Domain.h"
#include "Character.h"
#include "Item.h"
Item pistol(int which, float strength) {
// definition, see above
}
int main() {
Item w2 = pistol(2, 0.5);
return 0;
}
What is the problem with that function being in Item.h/Item.cxx?
What do I need to do to put it their?
undefined reference is a linking stage error.
You most probably missed to link with a compilation unit, missed to recompile a dependent compilation unit, or tried to have a template class/function definition not seen by the compiler from all your compilation units using it!