I'm having a headerfile called cnVector.h whose implementation is written in cnVector.cpp.
Those two files are located in the same directory.
cNormalCBP/
+ src/
+ cNormal/
+ cnUtils/
- cnVector.h
- cnVector.cpp
- main.cpp
The header contains a simple class definition.
class cnVector {
public:
cnVector(double, double, double);
inline cnVector cross(const cnVector&) const;
};
The implementation in the .cpp file is as follows:
#include "cnVector.h"
/* constructor */ cnVector::cnVector(double x, double y, double z)
: x(x), y(y), z(z) {
}
cnVector cnVector::cross (const cnVector& vOther) const {
return cnVector(
y * vOther.z + z * vOther.y,
z * vOther.x + x * vOther.z,
x * vOther.y + y * vOther.x );
}
Now, the following code from main.cpp breaks at line 3 because of an undefined reference to cnVector::cross(cnVector const&) const;
Note how the constructor-implementation is recognized, but not the cnVector::cross method.
int main() {
cnVector v1(1, 0, 0), v2(0, 1, 0);
cnVector v3 = v1.cross(v2);
}
I also get an error-message warning: inline function 'cnVector cnVector::cross(const cnVector&) const' used but never defined.
Copying the implementation into main.cpp works.
Can you explain to me why I can construct a cnVector instance but
the implementation of other methods are not recognized ?
Move your inline functions to your header file. Inline functions need their entire definitions in the header files because of how they integrate with the rest of your code. The compiler will (maybe) attempt to insert the code at all locations where the function is called, so it needs to be visible in the header file similar to how templates need to be entirely present in the header file.
Related
I encountered this problem when I try to compile my code
I thought it might be caused by header files including each other. But as far as I can tell I did not find any issues with my header files
Error LNK1169 one or more multiply defined symbols
found Homework2 D:\05Development\04 C_C++\C\DS Alg
class\Homework2\Debug\Homework2.exe 1
also, there's an error telling me that function Assert() has been declared elsewhere.
Error LNK2005 "void __cdecl Assert(bool,class
std::basic_string,class
std::allocator >)"
(?Assert##YAX_NV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z)
already defined in DataBase.obj Homework2 D:\05Development\04
C_C++\C\DS Alg class\Homework2\Homework2\dbTest.obj 1
here's the structure of my code:
function
void Assert(bool val, string s)
{
if (!val)
{
cout << "Assertion Failed!!: " << s << endl;
exit(-1);
}
}
is in Constants.h
A virtual class List includes Constants.h
#pragma once // List.h
#include "Constants.h"
An array list includes List class, in the AList class it calls the Assert function
#pragma once //AList.h
#include "List.h"
...
Assert((pos >= 0) && (pos < listSize), "Position out of range");
In the DataBase class I created a AList member
private:
AList<CData> set;
header looks like this:
#pragma once
#include "AList.h"
#include "CData.h"
and CData.h looks like this:
#pragma once
class CData
{
private:
std::string m_name;
int m_x;
int m_y;
public:
CData(std::string str = "null", int x = 0, int y = 0) : m_name(str), m_x(x), m_y(y) {}
// Helper functions
const std::string& GetName() const { return this->m_name; }
const int& GetX() const { return this->m_x; }
const int& GetY() const { return this->m_y; }
};
When you build your project, each .cpp file gets compiled separately into different object files. The once in #pragma once only applies to the compilation of a single .cpp file, not for the project as a whole. Thus if a .cpp file includes header A and header B, and header B also includes header A, then the second include of header A will be skipped.
However, if you have another .cpp file that includes A, A will be included in that object file again -- because #pragma once only works when compiling a single .cpp file.
An #include statement literally takes the content of the included file and "pastes" it into the file that included it. You can try this by looking at the output of the C preprocessor tool (cpp in the gcc toolchain). If you are using the gcc toolchain, you can try something like this to see the file after its includes have been applied:
cpp file.cpp -o file_with_includes.cpp
If you have a function in your header, like Assert in your example, the function gets replicated into each .cpp file you include it in.
If you have A.cpp and B.cpp, that both include your Constants.h file, each object file (.o or .obj depending on your environment) will include a copy of your Assert function. When the linker combines the object files to create a binary, both object files will declare that they provide the definition for Assert, and the linker will complain, because it doesn't know which one to use.
The solution here is either to inline your Assert function, like this:
inline void Assert(bool val, string s)
{
if (!val)
{
cout << "Assertion Failed!!: " << s << endl;
exit(-1);
}
}
or to provide its body in its own .cpp file, leaving only the function prototype in the header.
Constants.h:
void Assert(bool val, string s);
Constants.cpp:
void Assert(bool val, string s)
{
if (!val)
{
cout << "Assertion Failed!!: " << s << endl;
exit(-1);
}
}
Mind you, the Standard Library also offers assert(), which works nicely too. (see https://en.cppreference.com/w/cpp/error/assert).
#include <cassert>
...
assert(is_my_condition_true());
assert(my_variable > 23);
// etc..
Just keep in mind that the assert declared in cassert only works when compiling for Debug, and gets compiled out when building for Release (to speed up execution), so don't put any code in assert that has side effects.
#include <cassert>
...
// Don't call functions with side effects.
// Thus function decreases a "count" and returns the new value
// In Release builds, this line will disappear and the decrement
// won't occur.
assert(myclass.decrement_count() > 0);
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.
I am following this question for iterating over an enum.
enum class COLOR
{
Blue,
Red,
Green,
Purple,
First=Blue,
Last=Purple
};
COLOR operator++( COLOR& x ) { return x = (COLOR)(((int)(x) + 1)); }
COLOR operator*(COLOR c) {return c;}
COLOR begin(COLOR r) {return COLOR::First;}
// end iterator needs to return one past the end!
COLOR end(COLOR r) {return COLOR(int(COLOR::Last) + 1);}
The problem is that in my project, there are many cpp and hpp files which are compiled separately. It seems the compiler needs to have direct access to implementation of operator++. If I declare in a hpp and then implement in cpp file, I will face with error:
compiler warning: inline function ‘Color operator++(Color&)’ used but never defined
linker error: undefined reference to `operator++(instruction_type&)'
If I define it directly in hpp, I will face with another error
multiple definition of ...
for operator*, begin, and end in linker.
Adding the inline keyword in front of your 4 functions will allow them to be defined in the header without the multiple definition errors. For example:
inline COLOR operator*(COLOR c) {return c;}
Or you can include just the prototype in the .h file and define the functions in 1 .cpp file.
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;
}
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