Failed to create first library. `undefined reference to `main` - c++

I am attempting to create my first linux based static library. I am following the directions from this site here.
This is the code
#ifndef _ADDNUMBERS_H
#define _ADDNUMBERS_H
class AddNumbers
{
private:
int _a;
int _b;
public:
AddNumbers ();
~AddNumbers ();
void setA (int a);
void setB (int b);
int getA () const;
int getB () const;
int getSum () const;
}; // AddNumbers
#endif // _ADDNUMBERS_H
~/workspace/C++/AddNumbers/src/AddNumbers.cpp
#include "AddNumbers.h"
AddNumbers::AddNumbers ()
: _a(0), _b(0)
{
}
AddNumbers::~AddNumbers ()
{
}
void AddNumbers::setA (int a)
{
_a = a;
}
void AddNumbers::setB (int b)
{
_b = b;
}
int AddNumbers::getA () const
{
return _a;
}
int AddNumbers::getB () const
{
return _b;
}
int AddNumbers::getSum () const
{
return _a + _b;
}
This is the makefile I am using . The header and cpp files are next to each other
CC=g++
ifeq ($(DEBUG),yes)
CXXFLAGS=-Wall -g
LDFLAGS=-Wall -g
else
CXXFLAGS=-Wall
LDFLAGS=-Wall
endif
AR=ar
ARFLAGS=rcs
INC=AddNumbers.h
SRC=AddNumbers.cpp
OBJ=AddNumbers.o
OUT=libAddNumbers.a
INCLUDES= -I #./$(INCPATH)
default: $(OUT)
$(OUT): $(OBJ)
$(AR) $(ARFLAGS) $# $(OBJ) # The # means use the target name
%.o: %.cpp $(INC)
$(CC) $(CXXFLAGS) $(INCLUDES) -c $< -o $#
.PHONY: clean cleanall
clean:
rm -f *.o
cleanall: clean
rm -f $(OUT)
This is my output
admin#localhost lib$ make
g++ -Wall -I -c AddNumbers.cpp -o AddNumbers.o
/usr/lib/gcc/x86_64-redhat-linux/4.8.3/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [AddNumbers.o] Error 1
admin#localhost lib$
How can I fix this issue ?

I believe your argument-less -I is swallowing your -c argument so gcc doesn't see it and use compile-only mode.
Either give your -I argument a value or get rid of it and see if that works.

Related

How to access to a protected function with the overloading of the operator << ? C++

For a exercise in C++, I must to use a protected c++ in a function which overload the operator <<.
But we know that protected function is accessible in a class or with the keyword friend if we want to define the function in a cpp file.
For the moment, I have one abstract class and the main.
I dont't have any idea how I can to fix this error, and I wanted to finish as far as possible this exercice early ;)
Card.hpp
#ifndef CARD_HPP
#define CARD_HPP
#include <string>
#include <iostream>
class Card
{
std::string name;
protected:
virtual std::ostream & toStream(std::ostream & out){out << name;return out;}
public:
Card(std::string n):name(n){}
friend std::ostream & operator<<(std::ostream & out, const Card &c);
};
#endif
Card.cpp
#include <Card.hpp>
std::ostream & operator<<(std::ostream & out, const Card &c)
{
return c.toStream(out);
}
main.cpp
#include <Card.hpp>
using namespace std;
int main()
{
Card card("montain");
cout << card << "\n";
return 0;
}
Output
clang++ -Wall -std=c++14 -c -o obj/main.o src/main.cpp -I include
clang++ -Wall -std=c++14 -c -o obj/Card.o src/Card.cpp -I include
src/Card.cpp:5:12: error: member function 'toStream' not viable: 'this' argument has type 'const Card', but function is not
marked const
return c.toStream(out);
^
include/Card.hpp:12:32: note: 'toStream' declared here
virtual std::ostream & toStream(std::ostream & out){out << name;return out;}
^
1 error generated.
makefile:16: recipe for target 'obj/Card.o' failed
make: *** [obj/Card.o] Error 1
The makefile
CC = clang++
CFLAGS = -Wall -std=c++14
HDIR = include
ABSTRACT = obj/Card.o
.PHONY: doc
compile: bin/main
./bin/main
bin/main: obj/main.o ${ABSTRACT}
${CC} ${CFLAGS} -o $# $^
obj/%.o: src/%.cpp
${CC} ${CFLAGS} -c -o $# $< -I ${HDIR}
doc:
doxygen Doxyfile
clean:
rm obj/*.o
rm bin/*
cleanDoc:
rm doc/* -rf
The problem is not that the function is protected, but that it is not const.
src/Card.cpp:5:12: error: member function 'toStream' not viable: 'this' argument has type 'const Card', but function is not
marked const
return c.toStream(out);
As the error message says, c is const due to const Card &c, and as of that you can only call const member functions on c.
So either make your toStream member function const:
virtual std::ostream & toStream(std::ostream & out) const
Or change the streaming operator so that c is not const. But that's not recommended, you should only pass as non const ref if the function is expected to change/replace the passed argument:
std::ostream & operator<<(std::ostream & out, Card &c)

Makefile issue with Class template: clang warning linker input unused

I have 2 classes: a class template list.t with definition and implementation, and ticker.h and ticker.cpp, along with a driver program, main.cpp. I want to compile main.cpp to get to main.x which uses both the ticker and list class. This is my makefile so far.
# makefile for fx project
CC = g++
CFLAGS = -g -Wall -Wextra
default: main.x
main.x: main.o ticker.o list.o
$(CC) $(CFLAGS) -o $# main.o list.o ticker.o
list.o: list.t
$(CC) -c list.t
ticker.o: ticker.cpp
$(CC) -c ticker.cpp list.t
main.o: list.t ticker.cpp main.cpp
$(CC) -c main.cpp ticker.cpp list.t
But on executing the command make I am getting the following error:
make
g++ -c main.cpp ticker.cpp list.t
clang: warning: list.t: 'linker' input unused
g++ -c list.t
clang: warning: list.t: 'linker' input unused
g++ -g -Wall -Wextra -o main.x main.o list.o ticker.o
clang: error: no such file or directory: 'list.o'
make: *** [main.x] Error 1
List.t - (without implementations)
#ifndef LIST_T
#define LIST_T
#include <iostream>
template <typename T>
class List
{
public:
// constructors
List();
List(T);
List(const List&);
~List();
// member functions
List& operator = (const List&);
void PushFront (const T&);
void PushBack (const T&);
T PopFront();
T PopBack();
T& Front();
T& Back();
const T& Front() const;
const T& Back() const;
size_t Size() const;
bool Empty() const;
void Clear();
void Display (std::ostream&, char = '\0') const;
//private vars
private:
class Link
{
Link (const T& t) : element_(t), nextLink_(0), previousLink_(0) {};
T element_;
Link* nextLink_;
Link* previousLink_;
friend class List<T>;
};
Link* firstLink_;
Link* lastLink_;
};
I am sure this is a simple error, and I have scoured google for this error message, but I either am not fully understanding their solutions, or they are not working for me. Either way, let me know if you have a solution to this problem, or any other comments on the quality and structure of this makefile. Also any knowledge on why my flags are apparently being unused would be greatly appreciated!
Thanks!
You need -c in the command line only when you compile source files to create object files.
Change
main.x: main.o ticker.o list.o
$(CC) $(CFLAGS) -c main.o list.o ticker.o
to
main.x: main.o ticker.o list.o
$(CC) $(CFLAGS) -o $# main.o list.o ticker.o
^^^^^
$# is the file name of the target of the rule.
See GNU make: Automatic Variables for more such variables.
The makefile should be the following:
CC = g++
CPPFLAGS = -g -Wall -Wextra
default: main.x
main.x: main.o ticker.o
$(CC) -o $# main.o ticker.o
ticker.o: ticker.cpp
$(CC) -c ticker.cpp $(CPPFLAGS)
main.o: list.t main.cpp
$(CC) -c main.cpp $(CPPFLAGS)
You don't compile a template file. The implementation should be inside the same file as the class declaration (putting the .hpp extension would be better also). Then the template must be included in the other files. For example, in the main, put a #include "list.t" directive.

undefined reference to vtable for inheriting classes

I'm trying to develop a neural network in c++.
I refactored my code utilizing class-inheritance, to allow me to have different kinds of layers, whose neurons could be iterated over in sequence.
My problem is, that my linker (ld invoked by g++) complaines about undefined references to vtables and typeinfo-objects.
As far as I know, the error "undefined reference to vtable for class" comes from not implemented pure virtual methods in base classes, but unfortunately I not was able locate the error more percisely.
make all:
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Test2dSparselyNeuralNet.o Test2dSparselyNeuralNet.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o NeuralNet.o NeuralNet.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Sparsely2dNeuralNetwork.o Sparsely2dNeuralNetwork.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Connection.o Connection.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Layer2d.o Layer2d.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o Neuron2dIterator.o Neuron2dIterator.cpp
g++ -Wall -fmessage-length=0 --std=c++11 -w -c -o input/2dinput/cross/cross.o input/2dinput/cross/cross.cpp
g++ -o bin/neural_net_2d Test2dSparselyNeuralNet.o NeuralNet.o Sparsely2dNeuralNetwork.o Connection.o Layer2d.o Neuron2dIterator.o input/2dinput/cross/cross.o
Layer2d.o: In function `Layer::Layer()':
Layer2d.cpp:(.text._ZN5LayerC2Ev[_ZN5LayerC5Ev]+0x13): undefined reference to `vtable for Layer'
Layer2d.o: In function `Iterator::Iterator()':
Layer2d.cpp:(.text._ZN8IteratorC2Ev[_ZN8IteratorC5Ev]+0xf): undefined reference to `vtable for Iterator'
Layer2d.o: In function `Layer::~Layer()':
Layer2d.cpp:(.text._ZN5LayerD2Ev[_ZN5LayerD5Ev]+0x13): undefined reference to `vtable for Layer'
Layer2d.o:(.rodata._ZTI7Layer2d[_ZTI7Layer2d]+0x10): undefined reference to `typeinfo for Layer'
Neuron2dIterator.o:(.rodata._ZTI16Neuron2dIterator[_ZTI16Neuron2dIterator]+0x10): undefined reference to `typeinfo for Iterator'
collect2: error: ld returned 1 exit status
make: *** [neural_net_2d] Error 1
makefile:
CXXFLAGS = -Wall -fmessage-length=0 --std=c++11 -w
CXXFLAGS_DEBUG = -g -Wall -fmessage-length=0 --std=c++11 -w
SAMPLES = input/2dinput/cross/cross.o
OBJS = Test2dSparselyNeuralNet.o NeuralNet.o Sparsely2dNeuralNetwork.o Connection.o Layer2d.o Neuron2dIterator.o ${SAMPLES}
LIBS =
TARGET = neural_net_2d
$(TARGET): $(OBJS)
$(CXX) -o bin/$(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
debug: $(OBJS)
$(CXX) -o bin/$(TARGET) $(OBJS) $(LIBS) $(CXXFLAGS_DEBUG)
clean:
rm -f $(OBJS) $(TARGET)
Layer.h
#ifndef LAYER_H
#define LAYER_H
#include "Neuron.h"
#include "Iterator.h"
class Layer
{
protected:
// biasNeuron
Neuron biasNeuron = 1.0;
public:
inline Layer() : biasNeuron(1.0) {}
virtual Iterator& start();
virtual Neuron& front(void);
virtual Neuron& back(void);
virtual int size();
protected:
private:
};
#endif // LAYER_H
Layer2d.h
#ifndef LAYER2D_H
#define LAYER2D_H
#include "Layer.h"
class Layer2d : public Layer
{
public: std::vector<std::vector<Neuron> > _neurons;
public:
Layer2d();
virtual ~Layer2d();
Iterator& start();
Neuron& front(void);
Neuron& back(void);
int size();
protected:
private:
};
#endif // 2DLAYER_H
Layer2d.cpp
#include "Layer2d.h"
#include "Neuron2dIterator.h"
class Neuron2dIterator;
Iterator& Layer2d::start(void)
{
Neuron2dIterator& it = (*new Neuron2dIterator(*this));
return it;
}
Neuron& Layer2d::front(void)
{
Neuron& frontNeuron = this->_neurons.front().front();
return frontNeuron;
}
Neuron& Layer2d::back(void)
{
Neuron& backNeuron = this->_neurons.back().back();
return backNeuron;
}
int Layer2d::size(void)
{
int size = this->_neurons.back().size() * this->_neurons.size();
return size;
}
Layer2d::Layer2d()
{
//ctor
}
Layer2d::~Layer2d()
{
//dtor
}
LineLayer.h
#ifndef LINELAYER_H
#define LINELAYER_H
#include "Layer.h"
#include "Neuron.h"
#include <vector>
using namespace std;
class LineIterator;
class LineLayer : public Layer
{
public: std::vector<Neuron> _neurons;
public:
LineLayer();
protected:
private:
};
#endif // LINELAYER_H
LineLayer.cpp
#include "LineLayer.h"
#include "LineIterator.h"
Iterator& LineLayer::start()
{
LineIterator& it = (*new LineIterator());
return it;
}
Neuron& LineLayer::front()
{
Neuron& frontNeuron = this->_neurons.front();
return frontNeuron;
}
Neuron& LineLayer::back()
{
Neuron& backNeuron = this->_neurons.back();
return backNeuron;
}
int LineLayer::size()
{
return this->_neurons.size();
}
LineLayer::LineLayer()
{
//ctor
}
LineLayer::~LineLayer()
{
//dtor
}
Thnx for help!
As explained at https://gcc.gnu.org/wiki/VerboseDiagnostics#missing_vtable the vtable will be in the same object file as the first non-inline virtual function, which is Layer::start. You haven't defined that function, so the compiler never generated the vtable.
To fix the linker error be sure you have provided a definition for the first non-inline virtual function declared in the class.

Undefined reference to own files

I have the following Makefile to make my project:
# can be set by the user
LD_FLAGS ?= $(if $(GENERATE_EXECUTABLE),,-shared)
LIBS_FLAGS ?=
INCLUDE_FLAGS ?=
CXX_FLAGS ?= -O3 -Wall -std=c++11
objects = Connector.cpp main.cpp
defines := $(objects:.o=.def)
-include $(defines)
# main target
bin/o.exe: $(objects)
#echo '[LD] $^ > $#'
$(CXX) $(LD_FLAGS) $^ -o $# $(LIBS_FLAGS)
define generate_def
echo '[DEF] $< > $#'
$1 -MM $(INCLUDE_FLAGS) $2 $< > $#
mv -f $# $#.tmp
sed -e 's|.*:|$#:|' < $#.tmp > $#
sed -e 's/.*://' -e 's/\\$$//' < $#.tmp | fmt -1 | \
sed -e 's/^ *//' -e 's/$$/:/' >> $#
rm -f $#.tmp
endef
# Compile C++-Files with an appropriate def-file
obj/c++/%.def: %.cpp
#$(call generate_def,$(CXX),$(CXX_FLAGS))
$(objectscxx): obj/c++/%.o: %.cpp obj/c++/%.def # C++-Files
#echo '[CXX] $< > $#'
$(CXX) -c $< $(INCLUDE_FLAGS) $(CXX_FLAGS) -o $#
all: bin/o.exe
main.cpp includes Connector.h and Connector.cpp implements the function declared in Connector.h. Everything compiles fine until the linking stage.
Now when I run it the output is the following:
make all
[DEF] src/main.cpp > obj/c++/src/main.def
[DEF] src/Connector.cpp > obj/c++/src/Connector.def
[CXX] src/Connector.cpp > obj/c++/src/Connector.o
g++ -c src/Connector.cpp -O3 -Wall -g -std=c++11 -o obj/c++/src/Connector.o
[CXX] src/main.cpp > obj/c++/src/main.o
g++ -c src/main.cpp -O3 -Wall -g -std=c++11 -o obj/c++/src/main.o
[LD] obj/c++/src/Connector.o obj/c++/src/main.o obj/res/test.txt.o > bin/o.exe
g++ -static obj/c++/src/Connector.o obj/c++/src/main.o obj/res/test.txt.o -o bin/o.exe
obj/c++/src/main.o: In function `SpecialConnector::~SpecialConnector()':
C:\Users\Carbon\Documents\Eclipse-Workbench\EpicRPG/src/main.cpp:35: undefined reference to `engine::Connector<SpecialReceiver>::~Connector()'
/**
* More undefined references
*/
obj/c++/src/main.o:C:\Users\Carbon\Documents\Eclipse-Workbench\EpicRPG/src/main.cpp:35: more undefined references to `engine::Connector<SpecialReceiver>::~Connector()' follow
collect2.exe: error: ld returned 1 exit status
make: *** [bin/o.exe] Error 1
Connector.h
/*
* Connector.h
*
* Created on: 03.06.2014
* Author: Carbon
*/
#pragma once
#ifndef CONNECTOR_H_
#define CONNECTOR_H_
#include <type_traits>
namespace engine
{
template<typename DataType, typename ConnectorType>
struct DefaultReceiver {
public:
DefaultReceiver() {
}
virtual ~DefaultReceiver() {
}
static const char* receive(DataType data, ConnectorType conn, void* options) {
return "b";
}
};
template<template<typename, typename> class Receiver = DefaultReceiver>
class Connector
{
public:
Connector();
virtual ~Connector();
template<typename DataType, typename ConnectorType>
std::enable_if<true, const char*>::type
receive(DataType i, ConnectorType c, void* o);
};
} /* namespace engine */
#endif /* CONNECTOR_H_ */
Connector.cpp
/*
* Connector.cpp
*
* Created on: 03.06.2014
* Author: Carbon
*/
#include "Connector.h"
namespace engine
{
template<template<typename, typename> class Receiver>
Connector<Receiver>::Connector()
{
// TODO Auto-generated constructor stub
}
template<template<typename, typename> class Receiver>
Connector<Receiver>::~Connector()
{
// TODO Auto-generated destructor stub
}
template<template<typename, typename> class Receiver>
template<typename DataType, typename ConnectorType>
std::enable_if<true, const char*>::type
Connector<Receiver>::receive(DataType input, ConnectorType connector, void* options) {
return Receiver<DataType, ConnectorType>::receive(input, connector, options);
}
} /* namespace engine */
If you need source-files please comment, I don't think it's necessary (yes, ALL functions etc. are declared, if I include Connector.cpp instead of Connector.h everything is fine).
My specs are: Eclipse M4.3, gcc version 4.8.0
This compile error is regards to template instantiating. To solve this problem, you can put the implementation of Class Connector into the header file.
This answer gives a very good explanation on the reason, please check it out.
Most compilers will need the definition of your template Connector in your source file (or alternatively a redeclaration of the template class in the source file)
in particular, the constructor and the destructor should be defined (only declared) in the header file.
In Connector.h :
template<template<typename, typename> class Receiver = DefaultReceiver>
class Connector
{
public:
Connector() {}
virtual ~Connector() {}
template<typename DataType, typename ConnectorType>
std::enable_if<true, const char*>::type
receive(DataType i, ConnectorType c, void* o) {}
};

ffs does not name a type in C++

I get compilation error when i try to compile the following..... Please comment.
Here is my code:
ffs.h
#ifndef FFS_H
#define FFS_H
#include <iostream>
#include <string>
#include "commands.h"
class ffs{
private:
Filesystem *filesys;
Superblock block;
void processCommands(InputParser command);
void performQuit();
void performInit(InputParser command);
public:
void acceptCommands();
ffs(){};
};
#endif
ffs.cpp
#include "ffs.h"
void ffs::acceptCommands(){
std::string input;
while(true){
std::cout<< "Enter command : ";
getline(std::cin,input);
InputParser parser(input);
processCommands(parser);
}
}
void ffs::performInit(InputParser command){
command.getCommand().pop_front();
int n = atoi(command.getCommand().front().c_str());
std::cout<< n << " : number of blocks "<<std::endl;
command.getCommand().pop_front();
int m = atoi(command.getCommand().front().c_str());
std::cout<<m << " : number of inode blocks" << std::endl;
command.getCommand().pop_front();
block.ninode=m;
Filesystem fs(n);
filesys = &fs;
}
void ffs::performQuit(){
///filesys->clean();
exit(0);
}
void ffs::processCommands(InputParser command){
std::string cmd=command.getCommandName();
if(cmd.compare(commands::Q())==0) performQuit();
else if (cmd.compare(commands::INIT())==0) performInit(command);
}
tester.h
#ifndef TESTER_H
#define TESTER_H
#include "ffs.h"
class ffs;
class tester{
private:
ffs ffsobj;
public:
void run(){ffsobj.acceptCommands()};
};
#endif
tester.cpp
#include "tester.h"
int main()
{
tester runner;
runner.run();
return 0;
}
ERROR:
g++ -c -Wall tester.cpp
tester.h:7: error: ffs does not name a type
tester.h: In member function void tester::run():
tester.h:9: error: ffsobj was not declared in this scope
tester.h:9: error: expected `;' before ˜} token
make: *** [tester.o] Error 1
Makefile:
CFLAGS=-c -Wall
CC=g++
all: flags.o InputParser.o commands.o Filesystem.o ffs.o tester.o
$(CC) flags.o InputParser.o commands.o Filesystem.o ffs.o tester.o -o runner.o
flags.o : flags.cpp flags.h
$(CC) $(CFLAGS) flags.cpp
InputParser.o : InputParser.cpp InputParser.h
$(CC) $(CFLAGS) InputParser.cpp
ffs.o: ffs.cpp ffs.h
$(CC) $(CFLAGS) ffs.cpp
commands.o: commands.cpp commands.h
$(CC) $(CFLAGS) commands.cpp
Filesystem.o: Filesystem.cpp Filesystem.h Superblock.h
$(CC) $(CFLAGS) Filesystem.cpp
tester.o: tester.cpp tester.h ffs.o
$(CC) $(CFLAGS) tester.cpp
#fileUtility.o : IFileUtility.h
# gcc -c IFileUtility.h
# Inode.h commands.h Filesystem.h
clean :
rm *.o
You can't use ffs as your class name, it already has a meaning in c++ (albiet an obscure one). Just pick a different name.
You got a #endif in your ffs.h file, without the befinning #if.
If you include ffs.h in your tester.h file, why do you declare class ffs; ?
Error is in following line:
class ffs;
class tester{
private:
ffs ffsobj; // <--- can't declare object for ffs; can be pointer/reference only
To declare an object of ffs type, class tester should be able to see its full definition. Otherwise you can just declare a pointer or reference of ffs type, if you have forward declared like that (ffs* or ffs&).
Remove the forward class declaration class ffs; from tester.h. It is unnecessary since you include ffs.h and then confuses the compiler when it tries to define a class member which it thinks it has not seen the definition for.
do not solve the "does not name a type" problem, but look at this line:
void run(){ffsobj.acceptCommands()};
the correct is:
void run(){ffsobj.acceptCommands();}