Function already defined error in C++ - c++

I have a file called "SimpleFunctions.h" defined as follow:
#ifndef SIMPLEFUNCTIONS_H
#define SIMPLEFUNCTIONS_H
namespace my_namespace {
double round(double r) { return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); }
float round(float r) { return round((double)r); }
}
#endif // SIMPLEFUNCTIONS_H
This file was previously included in only one file and it was working fine.
Now today I have included it in a second file and it no longer works. At link time, it tells me that the function is already defined in "firstfile.obj".
However, since I am using include guards, I would expect the functions to be defined only once, or am I missing something?

By default, these functions have external linkage. That means each translation unit has functions called double round(double r) and float round(float r), which causes a name collision at link time.
Some possible solutions are:
Declare the functions as static, which implies internal linkage
Inline the functions
Move the implementation out of the header and into a c/c++ file
Read more here:
What is external linkage and internal linkage?
By the way, include guards protect a single translation unit from including a header file multiple times. That's a different issue that what you're seeing here.

use 'inline'
inline double round(double r) { return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); }
inline float round(float r) { return round((double)r); }
The compiler won't necessarily inline the code (although for this short func it may) but the linker doesn't treat is as a separate function anymore.
Note - include guards stop the same include file being included more than once in the same source file (strictly speaking 'compilation unit') it doesn't stop it being included in separate source files that are linked together. That's why you normally declare it in a header but define the function in a c file

A better way to solve the problem is through templates. Your code will compile fine if you were to do something along the lines of:
template <class T>
T round (T r) {
return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
}
Your linker will stop complaining and you'll have a single function for all of your needs.
This solution can be improved with type traits. See boost::is_floating_point and boost::enable_if

Related

C++ implementation in header issues

I'm working on a fairly large project (3D graphics engine) and I've run into some trouble while restructuring the code a bit. I want to have all of my classes implemented in single files (only have .hpp rather than having both a .cpp and .hpp file for each class). I don't have a specific reason for doing it this way other than just wanting to, but I'm hoping to avoid discussions over what C++ best practices are.
When I do it this way I get a series of multiple definition errors that look like this:
/tmp/ccztDQam.o: In function `Point3DH::normalize()':
Renderer.cpp:(.text+0x736): multiple definition of `Point3DH::normalize()'
/tmp/ccawpiuU.o:main.cpp:(.text+0x1a6de): first defined here
/tmp/ccztDQam.o: In function `Point3DH::dot(Point3DH, Point3DH)':
Renderer.cpp:(.text+0x79e): multiple definition of `Point3DH::dot(Point3DH, Point3DH)'
/tmp/ccawpiuU.o:main.cpp:(.text+0x1a746): first defined here
/tmp/ccztDQam.o: In function `Point3DH::cross(Point3DH, Point3DH)':
Renderer.cpp:(.text+0x7d6): multiple definition of `Point3DH::cross(Point3DH, Point3DH)'
/tmp/ccawpiuU.o:main.cpp:(.text+0x1a77e): first defined here
...
The issue comes when the classes start including each other and code is repeated multiple times. It seems that header guards are not sufficient as explained in this answer. I'm wondering if there is any way to get around this or an alternate way to achieve the goal.
The project is organized into modules (folders) such as geometry or polygon which contain relevant classes so include paths go to the parent directory and then into the correct module and class
For reference, here is what one of the files looks like (./graphics/Raster.hpp):
#ifndef GRAPHICS_RASTER
#define GRAPHICS_RASTER
#include "../graphics/Colour.hpp"
#include <vector>
class Raster {
private:
std::vector<Colour> image;
std::vector<double> zBuffer;
int width;
int height;
public:
Raster(int, int, Colour);
void setPixel(int, int, double, Colour);
int getWidth();
int getHeight();
};
#endif
#ifndef GRAPHICS_RASTER_IMPLEMENTATION
#define GRAPHICS_RASTER_IMPLEMENTATION
#include "../graphics/Colour.hpp"
#include <vector>
#include <limits>
Raster::Raster(int width, int height, Colour clear) :
image(std::vector<Colour>(width*height, clear)),
zBuffer(std::vector<double>(width*height, -std::numeric_limits<double>::max())),
width(width),
height(height)
{}
void Raster::setPixel(int x, int y, double z, Colour c) {
if(x < 0 || x >= width || y < 0 || y >= height) return;
if(z <= zBuffer[(height - y - 1)*width + x]) return;
image[(height - y - 1)*width + x] = c;
zBuffer[(height - y - 1)*width + x] = z;
}
int Raster::getWidth() {return width;}
int Raster::getHeight() {return height;}
#endif
If you for some reason want to implement everything in header files, you have to make all your functions inline. Functions defined in class definitions are implicitly inline. Functions defined out-of-class have to be declared with inline keyword explicitly.
That's what you have to do with every definition that you have in the "implementation" section of your header - add explicit inline keyword to every function definition. E.g.
inline void Raster::setPixel(int x, int y, double z, Colour c) {
if(x < 0 || x >= width || y < 0 || y >= height) return;
if(z <= zBuffer[(height - y - 1)*width + x]) return;
image[(height - y - 1)*width + x] = c;
zBuffer[(height - y - 1)*width + x] = z;
}
and so on.
Of course, you can also move all your member function definitions into class definition (which will make them inline), but that will preclude such distinctly separated two-section header structure as you have now. I don't know how important it is to you.
Every time your header is included in a cpp file, you create a new copy of the implementation.
You need to make sure that the implementation is only used in one cpp file - or inline every method.
This guide have good ideas on doing that:
https://github.com/nothings/stb/blob/master/docs/stb_howto.txt
examples:
https://github.com/nothings/stb
Basically:
1-make a #define UNIQUE_NAME_IMP and #define UNIQUE_NAME_HEADER to make implementation and declaration visible on different files by using:
your implementation:
#ifdef _DECL_
type declaration
function prototype
#endif
#ifdef _IMPL_
code
#endif
and in another file that will use it:
#define _DECL_
#include <my_header.h>
code...
...
//use this only once to avoid
//duplicate symbol like you mentioned in your post.
#define _IMPL_
#include <my_header.h>
2-avoid memory allocation, make your functions use the memory you pass on with your structures.
3-avoid external dependencies. Each dependency will make you use flags or create requirements to comply before using your header...
4-use "static". This makes the implementation private to the source file that creates it.

C++ make error: object_var has not been declared [duplicate]

This question already has answers here:
error: Class has not been declared despite header inclusion, and the code compiling fine elsewhere
(9 answers)
Closed 7 years ago.
You could have forgot to include problemclass.h from the file where you are using ProblemClass.
You could have misspelled the name of ProblemClass either in its own header file or in the place where you are using it. This can be
hard to spot if it is a capitalization error such as writing
Problemclass or problemClass instead of ProblemClass.
You could have copy-pasted your inclusion guard #defines from one header file to another and then forgot to change the defined names.
Then only the first of those two included header files would take
effect.
You could have placed ProblemClass in a namespace A, in which case you must refer to ProblemClass as A::ProblemClass if you are referring
to it from outside the namespace A.
You may be using templates and not expecting two-phase lookup to work the way it does.
You could have misspelled the file name in your include. The compiler would not report an error on that if you also have an old
version of that file under the misspelled name.
You could have made ProblemClass a macro that only gets defined after you include problemclass.h, in which case what you see as
ProblemClass gets replaced by something else by the macro
preprocessor.
You could have defined ProblemClass in a header file other than problemclass.h and then problemclass.h actually defines something
else.
The above was taken from another similar question, I found the points useful but none actually solved my problem, stated hereunder:
I'm creating a natural language processor for a robot, giving the software various objects to represent real world items in its environment (Blocks world for now), one of the objects defined in Block:
/*
* Block.h
*
* Created on: 11 Mar 2015
* Author: Edward
*/
#ifndef BLOCK_HPP_
#define BLOCK_HPP_
#include "typedefinitions.h"
#include "dynamixel.h"
#include "BasicRobotFunctions.hpp"
class Block {
public:
bool grounded;
//TODO position is a deprecated variable, replace with distance from
//pos position;
int number;
int distance;
int object_brightness;
Block(BasicRobotFunctions basic);
virtual ~Block();
void setBrightness(int brightness);
void setGrounded(bool ground);
//void setPosition(int x, int y);
void setDistance(int number);
void setNumber(int number);
//pos getPosition();
int getNumber();
int getDistance();
bool getGrounded();
int getBrightness();
int lookAround(BasicRobotFunctions basic);
};
#endif /* BLOCK_H_ */
with source file:
/*
* Block.cpp
*
* Created on: 11 Mar 2015
* Author: Edward
*/
#include "Block.hpp"
#define DEFAULT_PORTNUM 3 // COM3
#define DEFAULT_BAUDNUM 1 // 1Mbps
Block::Block(BasicRobotFunctions basic) {
grounded = false;
number = Block::lookAround(basic);
}
Block::~Block() {}
void Block::setGrounded(bool ground){
grounded = ground;
}
/*
void Block::setPosition(int x, int y){
position.x = x;
position.y = y;
}*/
void Block::setDistance(int dist){
distance = dist;
}
void Block::setNumber(int num){
number = num;
}
bool Block::getGrounded(){
return grounded;
}
/*
pos Block::getPosition(){
return position;
}*/
int Block::getNumber(){
return number;
}
int Block::getDistance(){
return distance;
}
int Block::getBrightness(){
return object_brightness;
}
//TODO Arrange function to incorporate Turn() in BasicRobotFunctions
int Block::lookAround(BasicRobotFunctions basic){
int num = 0;
dxl_initialize(DEFAULT_PORTNUM,DEFAULT_BAUDNUM);
for(int i = 0;i<360;i++){
dxl_write_word(11,32,-255);
dxl_write_word(11,30,200);
basic.Step(1);
dxl_write_word(11,32,255);
dxl_write_word(11,30,100);
if(dxl_read_byte(100,32) >= dxl_read_byte(100,52)){
num++;
}
}
dxl_terminate();
return num;
}
void Block::setBrightness(int bright){
object_brightness = bright;
}
I am however receiving the following compilation error from the constructor and from the turnAround(BasicRobotFunctions) method:
In file included from Robot.hpp:11,
from BasicRobotFunctions.hpp:12,
from main.cpp:8:
Block.hpp:23: error: expected `)' before 'basic'
Block.hpp:35: error: 'BasicRobotFunctions' has not been declared
make.exe: *** [main.o] Error 1
Having checked my other classes utilizing objects as variables I get the same error.
In response to the points in the quote:
- BasicRobotFunctions.hpp is included
- the class name is spelt the same in all different instances mentioning it
- I didn't copy paste any inclusion guard
- I didn't use any namespaces in the project
- Nor am I using any templates
- the file name isn't misspelled in my include
- I haven't defined any macros in the program
- I made sure every class was defined in its own header file
Is there any other issue my system could possibly have, any mistake I'm making or simply anything I'm doing which is bad programming practice here?
The cause of your problem:
You have a header file circular dependency problem.
main.cpp includes BasicRobotFunctions.hpp
which includes Robot.hpp
which includes Block.hpp
which includes BasicRobotFunctions.hpp.
If your header files are properly guarded against multiple inclusion (which it seems that they are), Block.hpp won't see the definitions of BasicRobotFunctions.hpp because it is already in the middle of including it.
How to spot the problem:
The source of this problem is apparent in the compilation error message and in your Block.hpp file.
The compiler is reporting an error in Block.hpp, and it is describing line by line how it got to that file via inclusions. The source to your Block.hpp file makes it clear that it is trying to include BasicRobotFunctions.hpp.
The fix:
In your case, you can modify your method signatures in Block.hpp to use a (perhaps constant) reference to the BasicRobotFunctions type, and then forward declare the type. This allows you to eliminate the dependency on the BasicRobotFunctions.hpp header file. (Block.cpp would likely need to include both Block.hpp and BasicRobotFunctions.hpp.)
//...
#include "typedefinitions.h"
#include "dynamixel.h"
class BasicRobotFunctions; // Forward declaration
//...
Block(const BasicRobotFunctions &basic);
//...
int lookAround(const BasicRobotFunctions &basic);
//...
You may be able to avoid this problem in the future by minimizing what headers are required to allow your header file to compile. This means your header file should:
Use forward declarations to types that are used.
Use references to forward declared types.
You can check that your header file has minimized its dependencies by making sure it compiles by itself. I accomplish this by including the header file first in a corresponding source file, and then make sure the source file compiles.
// Foo.cpp
#include "Foo.hpp"
//...
Well you can put a forward declaration before the class as
class BasicRobotFunctions;
class Block {
public:
bool grounded;
//TODO position is a ...
but this kind of error means that the #include "BasicRobotFunctions.hpp"
don't declare the BasicRobotFunctions. It's possible a trouble with code guards?
The circular inclusion can be solved using the forward declaration, putting correct guards in headers and moving some includes to source files.

How can I be getting "already defined" linker errors here?

I'm making my first attempt at unit testing in C++, and I haven't used C++ in a number of years (I'm mainly a C# coder at the moment). It seems like I'm making a right pig's ear of it - I hope someone can steer me back onto the righteous path. I'm just getting started here and would really like to be implementing these tests using the best practice possible, so any and all comments are welcome, even though I'm most concerned with my linker error at present.
So, I have an overall solution "Technorabble", with sub-projects "CalibrationTool" and "CalibrationToolUnitTests".
CalibrationTool has a MathUtils.h file:
#ifndef __math_utils__
#define __math_utils__
#include "stdafx.h"
#include <vector>
namespace Technorabble
{
namespace CalibrationTool
{
double GetDoubleVectorAverage(std::vector<double> v)
{
double cumulativeValue = 0;
for(std::vector<double>::iterator iter = v.begin(); iter != v.end(); ++iter)
{
cumulativeValue += *iter;
}
return cumulativeValue / v.size();
}
}; // end namespace CalibrationTool
}; // end namespace Technorabble
#endif // !__math_utils__
(But no .cpp file as I was having all kinds of (somewhat similar) issues getting my template function working - so I ended up defining that inline).
Moving on to the Unit Tests project, I have a main.cpp:
#include "MathUtilsTest.h"
void RunMathUtilsTests();
int main()
{
RunMathUtilsTests();
// Other class tests will go here when I have things to test
}
void RunMathUtilsTests()
{
MathUtilsTest* mathUtilsTest = new MathUtilsTest();
mathUtilsTest->RunTests();
delete mathUtilsTest;
}
Finally, the header and cpp for the MathUtilsTest class, again, fairly simple:
.h:
#ifndef __MATH_UTILS_TEST__
#define __MATH_UTILS_TEST__
#include "CalibrationToolUnitTestsLogging.h"
#include "..\CalibrationTool\MathUtils.h"
class MathUtilsTest
{
public:
MathUtilsTest();
~MathUtilsTest();
bool RunTests();
private:
bool GetDoubleVectorAverageTest();
}; // end class MathUtilsTest
#endif
.cpp:
#include "MathUtilsTest.h"
#include <sstream>
bool MathUtilsTest::RunTests()
{
return GetDoubleVectorAverageTest();
}
MathUtilsTest::~MathUtilsTest()
{
}
MathUtilsTest::MathUtilsTest()
{
}
bool MathUtilsTest::GetDoubleVectorAverageTest()
{
bool passed = true;
std::vector<double> values;
for (int i = 1; i < 23; i++)
{
values.push_back(i);
}
// vector becomes: 1, 2, 3, 4, .....20, 21, 22. Average is 11.5
double expectedAverage = 11.5;
double calculatedAverage = Technorabble::CalibrationTool::GetDoubleVectorAverage(values);
if (calculatedAverage != expectedAverage)
{
std::ostringstream s;
s << calculatedAverage;
std::string avgString = s.str();
CalibrationToolUnitTestsLogging::Write("Failed MathUtilsTest.GetDoubleVectorAverageTest: " + avgString);
passed = false;
}
else
{
CalibrationToolUnitTestsLogging::Write("Passed MathUtilsTest.GetDoubleVectorAverageTest");
}
return passed;
}
This all seemed fine to me, I'm protecting my header with #ifndef, etc. But I'm still getting the following errors:
1) error LNK1169: one or more multiply defined symbols found
2) error LNK2005: "double __cdecl Technorabble::CalibrationTool::GetDoubleVectorAverage(class std::vector >)" (?GetDoubleVectorAverage#CalibrationTool#Technorabble##YANV?$vector#NV?$allocator#N#std###std###Z) already defined in main.obj C:_SVN\Technorabble\Windows Software\CalibrationToolUnitTests\MathUtilsTest.obj
How can this be? Can anyone spot where it's going wrong?
Functions defined in headers should be marked as inline:
inline double GetDoubleVectorAverage(std::vector<double> v)
{
}
If it's longer than a couple of lines, consider moving it to an implementation file.
pragmas or include guards don't protect against multiple definitions.
Note that you should pass v by const reference rather than by-value.
You are defining a function GetDoubleVectorAverage in a header. This means that it will be defined in every translation unit (i.e. every source file) that includes that header. If your program contains more than one such translation unit, then you'll have more than one definition - which isn't allowed.
Solutions are:
Add inline to the function definition, to relax this rule and allow multiple identical definitions; or
Move the function definition into a source file, and only declare it in the header.
I'm protecting my header with #ifndef
That only prevents the header from being included more than once within the same translation unit. It doesn't prevent inclusion from more than one unit.
Also, you shouldn't use a reserved name like __math_utils__ as a header guard, even if the internet is littered with examples of dodgy code doing that.
I was having all kinds of (somewhat similar) issues getting my template function working
Templates usually need to be defined in header files, to make the definition available at the point of use. Function templates are implicitly inline, but normal functions (like this one) aren't.

How to call a function from another header file in C++?

I have the following 3 files (1 *.cpp and 2 *.hpp) :
the main program file:
// test.cpp
#include<iostream>
#include"first_func.hpp"
#include"sec_func.hpp"
int main()
{
double x;
x = 2.3;
std::cout << sec_func(x) << std::endl;
}
-
the first_func.hpp header:
// first_func.hpp
...
double first_func(double x, y, x)
{
return x + y + x;
}
-
the sec_func.hpp header:
// sec_func.hpp
...
double sec_func(double x)
{
double a, b, c;
a = 3.4;
b = 3.3;
c = 2.5;
return first_func(a,b,c) + x;
}
How do I properly call first_func from within the sec_func.hpp file?
For most functions, the implementation should reside in a compilation unit, that is a file that is going to be compiled by itself and compiled once.
Headers are not to be compiled by themselves*, instead they are included by multiple compilation units.
That's why your function definitions should reside in compilation units (like .cpp), not in headers. Headers should contain only the declarations (i.e. without the body), just enough so that other compilation units would know how to call them.
For completeness, the functions that generally need to be defined in headers (as an exception) are:
inline functions
template functions** (classes too)
Footnotes:
* headers can actually be pre-compiled, but that's a solution for speeding up compilation and it doesn't alter their purpose; don't get confused by that.
** you can put template function definitions outside of the headers if you use explicit template instantiation, but that's a rare case; the point is that every compilation unit that wants to instantiate a template (apply arguments to it) needs to have its complete definition, that's why template function definitions go into headers too.
It's a bad practice to place function definition to .hpp files. You should place only function prototypes there. Like this:
first_func.hpp:
double first_func(double x, double y, double x);
first_func.cpp:
double first_func(double x, double y, double x)
{
return x + y + x;
}
The same for second func.
And then, wherever you want to call your first_func, you just include corresponding first_func.hpp in that cpp module, and write the call.
Thus, every your module consists of hpp with all declarations, and cpp with definitions (that is, the bodies). When you need to reference something from this module, you include its hpp and use the name (of constant, variable, function, whatever).
And then you must link everything together:
gcc main.cpp first_func.cpp second_func.cpp -o program
To define a function in a header, you must mark it inline to prevent multiple definitions.
If you want to do this instead of separating the implementation to a separate file, you'll need to provide a prototype before calling the function (either by including the header (prefered) or declaring the function yourself).
// sec_func.hpp
#include "first_func.hpp"
//or
double first_func(double x, y, x); //declaration
double sec_func(double x)
{
double a, b, c;
a = 3.4;
b = 3.3;
c = 2.5;
return first_func(a,b,c) + x;
}

LNK 2005 link errors for functions but not for class in Visual Studio 2010

I am now building a C++ DLL library. Today I have met a confusing problem: in this library I can define class but not functions. To be more specific, I give the following codes to illustrate my problem:
namespace fundamental
{
class Tree
{
public:
Tree() {};
~Tree() {};
int x;
};
/*int anyfunction()
{
return 1;
}*/
}
The above definition is in the header file, and this file will be invoked by other files. My problem is that if I commented the function part (int anyfunction()) everything was fine, but if I added this function, I would get the following errors:
page_analysis.obj : error LNK2005: "int __cdecl fundamental::anyfunction(void)" (?anyfunction#fundamental##YAHXZ) already defined in geo_box.obj
1>pa_region_properties.obj : error LNK2005: "int __cdecl fundamental::anyfunction(void)" (?anyfunction#fundamental##YAHXZ) already defined in geo_box.obj
My question is why I will get LNK2005 error only for functions but not for classes. Any ideas?
If you define something in a header file, then that definition will be duplicated in any translation unit (roughly speaking, every source file) that includes that header. Sometimes, multiple definitions are an error.
Classes can be defined in multiple translation units, as long as the definitions are identical; indeed, they must be defined in any translation unit that uses them.
Functions usually can't, but you can allow it by declaring it inline:
inline int anyfunction() {return 1;}
or you could move the definition to a single source file, and only declare it in the header:
// header
namespace fundamental {
int anyfunction();
}
// source file
int fundamental::anyfunction() {return 1;}
Most likely you have included that function via a header into different translation units (aka cpp-file). If you really need that function to be inlined, use "inline":
inline int anyfunction()
{
return 1;
}
HTH Torsten