include guards not working - c++

I've defined a util.h file with functions that i want to use throughout several different other files. This header has an include guard, however when i use it in two different files, I get a multiple definition of... error. What am i doing wrong?
I've read this but this pertains to variable declaration/definition. This answer seems more relevant but it's not clear to me how i can fix this.
// util.h
// include lots of standard headers
#include ...
#ifndef UTIL_H
#define UTIL_H
using namespace std;
// multiple definition of `randarr(int, int, int)`
int* randarr(int size, int min, int max) {
int *ret = new int[size];
for (int i=0; i<size; i++)
ret[i] = (int) (((double) rand() / RAND_MAX) * max) + min;
return ret;
}
// no error
template<typename T> void printarr(T* v, int begin, int end) {
for (int i=begin; i<end; i++)
cout << v[i] << " ";
cout << endl;
}
// multiple definition of `is_prime(int)`
bool is_prime(int n) {
if (n == 2 || n == 3 || n == 5) return true;
if (n <= 1 || (n&1) == 0) return false;
for (int i = 3; i*i <= n; i += 2)
if (n % i == 0) return false;
return true;
}
#endif
// example.cpp
#include ...// lots of standard includes
#include "util.h"
void f() {
randarr(...);
printarr(...);
is_prime(...);
...
}
// Main.cpp
#include "util.h"
int main() {
}

The include guards are not the cause of the error; you're violating the One Definition Rule. Since util.h is being included in 2 source files, the translation units created after preprocessing each source file will contain a definition of each of the functions, thus leading to the multiple definition error.
To get rid of the error, mark the functions inline
inline int* randarr(int size, int min, int max) {
// ...
}
template<typename T>
inline void printarr(T* v, int begin, int end) {
// ...
}
inline bool is_prime(int n) {
// ...
}

You are getting a linker error, not a compiler error. You have implemented the function randarr() in your util.h file, which means the compiler sees a copy of randarr() in each of example.cpp and Main.cpp. When the linker goes to link these together, it complains because you're not permitted to have more than one definition of the same function.
You have two choices:
declare randarr() as inline in the header file
move the definition for randarr() to a util.cpp file
Apply the same fix to is_prime().

You defined functions in a header file. This means, the code for these functions are included in both example.cpp and in Main.cpp. And it also means the code will be generated twice. This is the reason for the "multiple definition" error.
When you define the functions randarr() and is_prime() only once in a separate util.cpp, the errors will be gone.

Your header should only contain the prototype of your function. A prototype describes your function to other files, but do not implement it. The only exception is the template, because each template specialisation is build upon compile time.
If you implement your function in your header file, at linker time, you will find multiple times the function content, and that is why you are facing an error.
Move the implementation of randarr and is_prime to another file, and transform you util.h to :
#ifndef UTIL_H
#define UTIL_H
using namespace std;
int* randarr(int size, int min, int max);
template<typename T> void printarr(T* v, int begin, int end) {
for (int i=begin; i<end; i++)
cout << v[i] << " ";
cout << endl;
}
bool is_prime(int n);
#endif

Related

Not all of my constructors are being imported?

I'm making a heap class to be importable with heap.h and my constructors including bool types do not work, yet every other constructor and function imported works.
Here is what's in heap.h:
#ifndef __HEAP_INCLUDED__
#define __HEAP_INCLUDED__
#include <iostream>
#include <vector>
using namespace std;
class heap{
int capacity;
bool isMinHeap; //1 is min heap -- ascending order
vector<int> * content;
public:
heap();
heap(bool t);
heap(vector<int> * input);
heap(vector<int> * input, bool t);
void print();
void prettyPrint();
int parent(int i);
int leftChild(int i);
int rightChild(int i);
int size();
int getMax();
void insert(int data);
void heapifyDown(int index);
void heapifyUp(int index);
int invalidChild(int index);
int deleteMax();
int deleteMin();
bool minDir();
int at(int index);
};
vector<int> * heapSort(vector<int> * input);
void swap(vector<int> * vec, int a, int b);
#endif
Here are the defined constructors in heap.cpp. Note, all constructors work fine when I add a main to this file to test stuff:
class heap{
vector<int> * content;
int capacity = 256;
bool isMinHeap; //1 is min heap -- ascending order
public:
heap(){
content = new vector<int>;
isMinHeap = 0;
}
heap(bool t){
content = new vector<int>;
isMinHeap = t;
}
heap(vector<int> * input){
content = input;
isMinHeap = true;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
heap(vector<int> * input, bool t){
content = input;
isMinHeap = t;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
//other functions below
}
The constructors with bool do not work in main.cpp, which has #include "heap.h" at the top. The files are all in the same directory and I am compiling with this command: g++ heap.cpp main.cpp -o main. Why do two of my constructors not work?
The error I see is
/usr/bin/ld: /tmp/ccwomODk.o: in function `main':
main.cpp:(.text+0x4e2): undefined reference to `heap::heap(bool)'
collect2: error: ld returned 1 exit status
-Wall does not elaborate on the issue. I'm pretty sure the issue is with my linking somewhere because the constructors work inside of heap.cpp when I use them in there.
What you are doing with the class in the .cpp file is wrong. You are not allowed to define the class twice. There must only be one class heap { /*...*/ }; in the program (but it may be included in multiple .cpp files). Otherwise the one-definition-rule (ODR) is violated and the program has undefined behavior.
So remove everything you are showing from heap.cpp.
To define the constructors of heap in the heap.cpp file, you need to use this syntax:
#include "heap.h"
heap::heap() {
/*...*/
}
heap::heap(bool t) {
/*...*/
}
//...
and so on. The other member functions must be defined in a similar way, e.g.:
void heap::print() {
/*...*/
}
Furthermore, if you want to have a default member initializer as in
int capacity = 256;
add it in the declaration in the .h file instead.
I also want to add that having a pointer-to-std::vector as member is almost surely a wrong approach as well, but out-of-scope for the question.
When you declare a program element such as a class, function, or
variable, its name can only be "seen" and used in certain parts of
your program. The context in which a name is visible is called its
scope. For example, if you declare a variable x within a function, x
is only visible within that function body.
It seems you broke ODR rule so bad. Your class members including constructors has no body declared in the source file(heap.cpp).
Use '::' to make class members have a body:
//heap.cpp
"heap.h"
heap::heap()
{
}
heap:heap(vector<int> * input, bool t)
{
}
int heap::parent(int i)
{
return i;
}
// this is how you create a body for function that are class members
// the same should be done for all other functions

"Use of undeclared identifier 'IntQueue' " even though it is defined

I am getting an error message saying the use of undeclared identifier 'IntQueue' in vscode and I cannot figure out what is wrong.
I have tried renaming the file but still does not work. I created a separate header file that has the class defined and I included the header file in the main cpp file that has all the constructors defined. But I cannot figure out a way to solve the issue.
//This is the IntQueue.h header file
#ifdef _IntQueue_
#define _IntQueue_
#include<iostream>
#include<fstream>
using namespace std;
class IntQueue {
int* numbers;
int size;
int front;
int back;
public:
IntQueue (unsigned int n);
IntQueue();
~IntQueue();
int getSize() {return size;}
int getFront() {return front;}
int getBack() {return back;}
void incSize();
void pop();
int frontNumber();
void push(int i);
void reverse();
};
#endif
//This is the IntQueue.cpp file (incomplete)
#include "IntQueue.h"
IntQueue::IntQueue (unsigned int n) {
size = n;
numbers = new int[size];
front = 0;
back = 0;
}
IntQueue::IntQueue() {
size = 100;
front = 0;
back = 0
numbers = new int [size];
}
You need to change
#ifdef _IntQueue_
To
#ifndef _IntQueue_
When your .cpp file #include's your .h file, _IntQueue_ has not been declared yet, so the #ifdef skips the entire content of the .h file, and so the compiler doesn't know anything about your IntQueue class.

Function was not declared in this scope, even though header file is present

I'm trying to run some test code to learn c++, but I am getting an error telling me the reverseDigits function was not declared in the main.cpp scope:
error: 'reverseDigits' was not declared in this scope.
But the #include "Solutions.h" header was included in main.cpp, so I thought that it would be in scope.
I have checkout other questions, but the answers all relate to problems with circular header file inclusion, which I don't think is the problem here.
Do you know why I am seeing that error?
Solution.h
#ifndef SOLUTION_H
#define SOLUTION_H
class Solution {
public:
Solution();
~Solution();
int reverseDigits(int x);
};
#endif // SOLUTION_H
Solution.cpp
#include "Solution.h"
#include <string>
Solution::Solution()
{
}
Solution::~Solution()
{
}
int Solution::reverseDigits(int x) {
std::string num_string = std::to_string(x);
std::string reversed_num_string {};
for (int i = num_string.length() - 1; i > 0; i--) {
reversed_num_string.push_back(num_string[i]);
}
return stoi(reversed_num_string);
}
main.cpp
#include <iostream>
#include "Solution.h"
int main()
{
int x {123};
int result = reverseDigits(x);
std::cout << result << std::endl;
return 0;
}
You declared reverseDigits as a member function of the Solution class, then defined it without qualifying it as a member of Solution (Edit: You've since changed it to match declaration and definition, but at point of use, you're trying to use an unqualified function, not a member of a Solution object). The declaration in the .h file is visible, but the definition in the .cpp is unrelated, and not visible to main.cpp.
Declare the function outside the class (since it's clearly unrelated to the class), and it should work, changing to:
class Solution {
public:
Solution();
~Solution();
};
int reverseDigits(int x); // NOT inside the class definition
I'll note: I have no idea why you have a Solution class at all. Defining reverseDigits doesn't require it, so I'm not seeing the point. If this is part of some automated evaluation framework, you'll have to give more details
Along with ShadowRanger's valid suggestion, I'll highlight upon how you could have used the data as part of your Solution class and applied the function on it.
Refactoring your class to
class Solution {
public:
Solution(int data);
~Solution();
int reverseDigits();
private:
int m_data;
};
Solution::Solution(int data)
{
m_data = data;
}
Solution::~Solution()
{
}
Even though you could have used std::reverse, fixing the error on the i>=0 is needed to have your own reverse function
int Solution::reverseDigits() {
std::string num_string = std::to_string(m_data);
std::string reversed_num_string {};
for (int i = num_string.length() - 1; i >= 0; i--) {
reversed_num_string.push_back(num_string[i]);
}
return stoi(reversed_num_string);
}
Now call it from your main() as
int main() {
int x = 123;
Solution sol(x);
std::cout << sol.reverseDigits() << std::endl;
return 0;
}

function definition in header file in c++

I have a simple cpp project that has one .cpp file(a.cpp) and two .h files (h1.h and h2.h).
In a.cpp, I have :
#include "h2.h"
#include "h1.h"
In h1.h, I have :
double abc = fun1(a, b); //using fun1() here. a and b are string types.
In h2.h, I have :
double fun1(string a, string b)
{ //definition
}
Error: in h1.h => fun1() in not declared in this scope.
Query is, m I doing this right? can one put function definition in a header file? should I use inline here?
Edit:
here is the h1.h
void checkForOneToOneSimilarity(vector <string> & folder1, vector <string> & folder2)
{
int i=0, j=0, l1 = folder1.size(), l2 = folder2.size();
//chunking(folder1[0]);
while(i < l1 && j < l2)
{
if(folder1[i] == folder2[j])
{
double similarity = fun1(folder1[i], folder2[j]);
i++;
j++;
}
else if(folder1[i] > folder2[j]) j++;
else i++;
}
}
You have declared double fun1() in h2.h,
but you called the function double fun1(std::string, std::string).
The compiler searches the definition double fun1(std::string, std::string) which is not declared.
You should change the function header in h2.h to double fun1(string a,string b)
you declared fun1() in h2.h and called the function h1.h so when the compiler search about fun1() it will not found it
try to include"h2.h" in the "h1.h" file
You can place function definitions in header files.
but here two things are wrong
You are calling fun1 inside h1.h , but it defined in h2.h. so h1.h cannot see the definition in h2.h.
for overcome this include h2.h to h1.h
Your function call and definition miss match.
function definition should be
double fun1(string a, string b)
{ //definition
}
matching function call should be
double abc = fun1("some string 1", "some string 2");
Append:
correct three files should be
h1.h
double addTwoStringNumbers (string a, string b)
{
double tot = atof(a.c_str()) + atof(b.c_str());
return tot;
}
h2.h
#include "h1.h"
void showValue()
{
double total = addTwoStringNumbers("2", "3");
std::cout << total << std::endl;
}
a.cpp
#include "h2.h"
int main()
{
showValue();
return 0;
}

redefinition of template<class T> in C++

I have searched and searched for a solution to my problem but I cannot seem to find one. I am using Code::Blocks and I am getting a redefinition error of a template class.
Here is my "vectorAux.h" file:
#ifndef vectoraux_h
#define vectoraux_h
#include <vector>
#include <algorithm>
#include <iostream>
template <typename T>
void removeDup(std::vector<T> & v);
template <typename T>
unsigned seqVectSearch(const std::vector<T> & v, unsigned first,
unsigned last, const T& target);
template <typename T>
void writeVector(const std::vector<T> & v);
#include "vectorAux.cpp"
#endif
and here is my "vectorAux.cpp" file:
#include "vectorAux.h"
#include <vector>
#include <algorithm>
#include <iostream>
template <typename T>
void removeDup(std::vector<T> & v)
{
std::vector<int> vector1;
unsigned i, last = v.size();
for(int j = 0; j <= v.size(); j++)
{
std::cout << seqVectSearch(v, j, last, j);
if(seqVectSearch(v, j, last, j) != v[i])
vector1.push_back(seqVectSearch(v, j, last, j));
}
}
template <typename T>
unsigned seqVectSearch(const std::vector<T> & v, unsigned first,
unsigned last, const T& target)
{
unsigned i = first;
while((v[i] != target) && (v[i] <= last))
{
if(v[i] == target)
return i;
i++;
}
return last;
}
template <typename T>
void writeVector(const std::vector<T> & v)
{
unsigned i;
unsigned n = v.size();
for (i = 0; i < n; i++)
std::cout << v[i] << ' ';
std::cout << std::endl;
}
the final file for this program is "vectorDriver.cpp" but this one has no errors. This one just runs the program by calling the functions:
#include "vectorAux.h"
#include <vector>
#include <iostream>
void fillVector(std::vector<int> & vect);
int main()
{
using namespace std;
vector<int> vect;
fillVector(vect);
cout << "Testing removeDup" << endl;
cout << "Original vector is ";
writeVector(vect);
removeDup(vect);
cout << "Vector with duplicates removed is ";
writeVector(vect);
cout << endl;
writeVector(vect);
return 0;
}
void fillVector(std::vector<int> & vect)
{
int arr[] = {1,7,2,7,9,1,2,8,9};
unsigned arrsize = sizeof(arr)/sizeof(int);
vect = std::vector<int>(arr, arr+arrsize);
}
I would really appreciate any and all help/advice that is given! I have looked around for a while and each source that I have found has said to guard the header file, but I have already done that and my problem still ensues.
You include vectorAux.cpp in vectorAux.h. I would guess that you are also compiling vectorAux.cpp separately. So you end up compiling the code in vectorAux.cpp twice.
Answer is simple, move the code from vectorAux.cpp to vectorAux.h, delete vectorAux.cpp, you don't need it.
Template code almost always goes in header files.
The contents of your "VectorAux.cpp" should be inside the "VectorAux.h" because you define a template class.
The simple answer is: Templates should not be split into source and header files. Keep it all in the header file when using templates.
Remove your .cpp of your templated class from your project source files. You are currently compiling the .cpp file twice; once because it is in your project and secondly because your .h is including it. Also, remove the .h inclusion from your .cpp, you don't need it since the header is including the .cpp at the bottom. This is one of the unfortunate problems of separating out templated classes.
The error happens during the compilation of the vectorAux.cpp file, because you are including the header file, which in turn includes the implementation file. This way, you end up with the content of the cpp file being duplicated.
If you really do want to split the implementation and declaration of the template functions into two separate files, there are two things you should do:
Don't include the headerfile in the implementation file.
Don't add the cpp file to the files being translated by the compiler.
Any one of those two options will get rid of your compiler error, but you really should do both.