I have a problem with Visual Studio 2012 & 2015 about the fact than it's seem than the "ifndef" don't work. I use the "ifndef" for "NAN" and "ifndef" for the header file and it's said these 2 errors (see the image). When I add the link "#include"Outil.h"" in the header of other file, I see the same message of error.
I always do like this before and it's always work. I don’t understand why it's doesn't work now even with only two files.
I also try to change the name of the first function "realoc_ungraded" but it's doesn't work and I get the same error.
Message of error
The message:
1) Warning: C4005: 'NAN': macro redefinition of math.h
2) Error: LNK2005: "struct tab_dynamo __cdecl realoc_ugraded(struct tab_dynamo,unsigned int)" (?realoc_ugraded##YA?AUtab_dynamo##U1#I#Z) already defined in main.obj Project1
3) Error: LNK1169: one or more multiply defined symbols found Projet
There is the code of the different file:
File main.cpp
#include"Outil.h"
int main(void) {
return 0;
}
File Outil.h
#ifndef LIBRARY_OF_TOOLS
#define LIBRARY_OF_TOOLS 0
#define _USE_MATH_DEFINES
//NAN not defined in Visual Studio 2012, so I use the def. of VS 2015
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
#include<iostream>
#include<string>
using namespace std;
#include<cmath>
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#define ERROR_ADRESSE 0xcccccccc //default when not initialised
#define DEFAULT_LENGHT_TAB 1
//-----------------------------------------
typedef double type_data; //the type for calculation
//-----------------------------------------
/*Struct for my array*/
typedef struct {
type_data *tab;
unsigned int length;
}tab_dynamo;
//-----------------------------------------
template<typename T>
bool verify_ptr(const T *ptr) {
return (ptr == NULL || ptr == (T*)(ERROR_ADRESSE));
}
//-----------------------------------------
template<typename T>
void see_tab(const T *tab, const unsigned int taille) {
unsigned int i;
cout << endl << endl;
if (verify_ptr(tab) == false && taille > 0) {
cout << endl;
for (i = 0; i<taille; ++i) {
cout << tab[i] << "\t";
}
}
cout << endl << endl;
}
//-----------------------------------------
template<typename T>
T* realoc_ungraded(const T* original_tab, unsigned int *length, const unsigned int new_length) {
T* new_tab = NULL;
unsigned int precedent_length = 0, i;
/*1) Exception case to directly exit*/
if (new_length == 0) {
return NULL;
}
/*2) Verification of the ptr of the length*/
if (verify_ptr(length)) {
length = (unsigned int*)calloc(1, sizeof(unsigned int));
assert(length);
}
precedent_length = *length;
*length = new_length;
/*4) Creation of the new tab.*/
new_tab = (T*)calloc(*length, sizeof(T));
assert(new_tab);
/*5) To transfert data of the original tab to the new tab*/
if (precedent_length != 0 && verify_ptr(original_tab) == false) {
for (i = 0; i < precedent_length && i < new_length; ++i) {
new_tab[i] = original_tab[i];
}
}
return new_tab;
}
//-----------------------------------------
//Version with the use of the struct "tab_dynamo"
tab_dynamo realoc_ungraded(tab_dynamo original_tab, const unsigned int new_length) {
tab_dynamo tableau = { NULL, 0 };
tableau.tab = realoc_ugraded(original_tab.tab, &original_tab.length, new_length);
tableau.length = new_length;
return tableau;
}
#endif
File Outil.cpp:
#include"Outil.h"
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
When preprocessor process these, the NAN is defined because it's not defined yet.
#include<cmath>
Then cmath maybe include math.h, and found NAN is defined by yours.
You can try to change the sequence of include and your definition.
#include <cmath>
#ifndef NAN
#define NAN ((float)(std::numeric_limits<float>::infinity*0.0F))
#endif
B.T.W If you compile using gcc, you could use -E option to see the output of preprocessor and know how the preprocess expand the macros.
Related
I was trying to write an array of ints to a binary file and then read the just written file and write it in another array (of the same size of the first), but i don't understand why the second array contains the correct numbers only until 25 (its 26th element, since numbers i wrote in the first start from 0).
A very weird thing i noticed, is that if i replace 'x[i] = i;' with 'x[i] = i * 3;' in the first for cycle in main, i obtain the correct numbers printed until 279 instead of 25 (and 25*3 != 279).
How could I write/read binary files to/from raw arrays in C++?
main.cpp:
#include "arrays_binary_files.hpp"
#include <iostream>
int main()
{
int x[1000];
//#if 0
for (size_t i{ 0 }; i != sizeof x / sizeof * x; ++i)
x[i] = i;
//#endif
int y[sizeof x / sizeof *x];
std::cout << "scrivo x su x.bin? [invio per continuare] _";//write?
(void)getchar();
std::cout << "\nscrivo x su x.bin...";//writing...
arrToBinFile(x, sizeof x / sizeof * x, "x.bin");
std::cout << "\nscritto x su x.bin";//written!
std::cout << "\n\nscrivo x.bin su y? [invio per continuare] _";//read?
(void)getchar();
std::cout << "scrivo x.bin su y...";//reading...
binFileToArr("x.bin", y, sizeof y / sizeof * x);
std::cout << "\nscritto x.bin su y";//read!
std::cout << "\n\nvisualizzo y? [invio per continuare] _";//show?
for (size_t i{ 0 }; i != sizeof y / sizeof * y; ++i) {
std::cout << '\n' << y[i];//stampa bene solo fino a 25
(void)getchar();
}
return 0;
}
arrays_binary_files.hpp:
#ifndef arrays_binary_files_hpp_included
#define arrays_binary_files_hpp_included
#include <fstream>
#include <filesystem>
//namespace {
/*
* gives internal linkage (like specifying static for everything), so that each
* function is "local" in each translation unit which is pasted in by #include
*/
//i tried to inline in order to debug using breakpoints, but i didn't understand the same where the bug is
inline char arrToBinFile(const int inputArray[], const size_t inputArrayLength, const std::string& fileName) {
std::ofstream outputData;
outputData.open(fileName);
if (outputData) {
outputData.write(reinterpret_cast<const char*>(inputArray), sizeof(int) * inputArrayLength);
outputData.close();
return 0;
}
else {
outputData.close();
return -1;
}
}
//i tried to inline to debug using breakpoints, but i didn't understand the same where the bug is
inline char binFileToArr(const std::string& fileName, int outputArray[], const size_t outputArrayLength) {
std::ifstream inputData;
inputData.open(fileName);
if (inputData /*&& std::filesystem::file_size(fileName) <= outputArrayLength*/) {
inputData.read(reinterpret_cast<char*>(outputArray), sizeof(int) * outputArrayLength);
inputData.close();
return 0;
}
else {
inputData.close();
return -1;
}
}
//}
#endif
screenshot of the console in case of leaving the main function in main.cpp as it is:
screenshot of the console in case of replacing 'x[i] = i;' with 'x[i] = i * 3;' in the main function in main.cpp:
When I try to compile my implementation file using g++ -c Sorting_Functions.cpp, I get this message
error: use of undeclared identifier 'IntSort'
IntSort.h
#ifndef INTSORT_H_
#define INTSORT_H_
#include "Sorting_Functions.cpp"
class IntSort
{
public:
IntSort();
void print();
private:
int arr[5];
int len;
};
#endif
Sorting_Functions.cpp
#include "IntSort.h"
using namespace std;
IntSort::IntSort()
{
arr[0] = 7;
arr[1] = 3;
arr[2] = 2;
arr[3] = 6;
arr[4] = 4;
len = 5;
}
// prints the lists to the user
void IntSort::print()
{
cout << "{ ";
for (int i = 0; i < len; i++) {
cout << arr[i] << " ";
}
cout << "}";
}
The problem is the inclusion of a source file (.cpp or .cc). Only header files (.h) should be included, and all source files should be compiled. Remove the source file #include and the code should be fine.
The "undeclared identifier" error is caused by Sorting_Functions.cpp including IntSort.h which in turn includes Sorting_Functions.cpp - the compiler will first see the type IntSort being used, which at this point has not yet been declared (which happens in IntSort.h after the #include).
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 2 years ago.
I am working with my own custom header file for the first time in C++. The goal of this program is to create a dice class that can be used to create an object oriented dice game.
When I go to run my program (made of three files (header/class specification file, class implementation file, and finally the application file), I am getting an error:
undefined reference to `Die::Die(int)'
I have about six of these errors when running app.cpp, one for every time I try to access information from my Die class.
Full Error Message
My Three Files
Die.h
#ifndef DIE_H
#define DIE_H
#include <ctime>
//#include
class Die
{
private:
int numberOfSides=0;
int value=0;
public:
Die(int=6);
void setSide(int);
void roll();
int getSides();
int getValue();
};
#endif
Die.cpp
#include <iostream>
#include <cstdlib>
#include <ctime>
#include "Die.h"
using namespace std;
Die::Die(int numSides)
{
// Get the system time.
unsigned seed = time(0);
// Seed the random number generator.
srand(seed);
// Set the number of sides.
numberOfSides = numSides;
// Perform an initial roll.
roll();
}
void Die::setSide(int side=6){
if (side > 0){
numberOfSides = side;
}
else{
cout << "Invalid amount of sides\n";
exit(EXIT_FAILURE);
}
}
void Die::roll(){
const int MIN_VALUE = 1; // Minimum die value
value = (rand() % (numberOfSides - MIN_VALUE + 1)) + MIN_VALUE;
}
int Die::getSides()
{
return numberOfSides;
}
int Die::getValue()
{
return value;
}
app.cpp
#include <iostream>
#include "Die.h"
using namespace std;
bool getChoice();
void playGame(Die,Die,int &, int &);
int main()
{
int playerTotal=0;
int compTotal=0;
Die player(6);
Die computer(6);
while(getChoice()){
playGame(player, computer, playerTotal, compTotal);
getChoice();
}
}
void playGame(Die play, Die comp, int &pTotal, int &cTotal){
//add points
play.roll();
pTotal += play.getValue();
comp.roll();
cTotal += comp.getValue();
//show points each round
cout << "You have " << pTotal << " points;\n";
}
bool getChoice(){
bool choice;
cout << "Would you like to roll the dice? (Y/N): ";
cin>> choice;
return choice;
}
You should compile both app.cpp and Die.cpp at the same time:
g++ app.cpp Die.cpp
I'm running omnet++ 4.6 for around 6months now. When I tried building my project after a few changes:
removing a header file from the project
adding more files to my includes folder
I get this error
Creating shared library: ../out/gcc-debug/src/libinet.dylib
Undefined symbols for architecture x86_64:
"BloomFilter::BloomFilter(unsigned long, int, unsigned long, ...)", referenced from:
AODVRouting::AODVRouting() in AODVRouting.o
AODVRouting::AODVRouting() in AODVRouting.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[1]: *** [../out/gcc-debug/src/libinet.dylib] Error 1
make: *** [all] Error 2
My project used to build and run fine before this.
This is .cc file:
#include "BloomFilter.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <cstdarg>
#include <exception>
#include <stdio.h>
#include <string.h>
using namespace std;
#define SETBIT(a, n) (a[n/CHAR_BIT] |= (1<<(n%CHAR_BIT)))
#define GETBIT(a, n) (a[n/CHAR_BIT] & (1<<(n%CHAR_BIT)))
// The Constructor
BloomFilter::BloomFilter(size_t size,int hash_k, size_t nfuncs, ...) {
va_list l;
unsigned int n;
try {
this->a=new char[(size+CHAR_BIT-1)/CHAR_BIT];
}
catch(const std::exception& e)
{
// If we get here is that there is an allocation error .
// We must free the memory .
delete(this);
// std :: cerr << "ERROR: " << e.what () << endl;
// Then raise the exception to indicate that an error occurred.
throw;
}
try {
this->funcs= new hashfunc_t[nfuncs];
}
catch(const std::exception& e){
delete(this->a);
delete(this);
}
va_start(l, nfuncs);
for(n=0; n < nfuncs; ++n) {
this->funcs[n]=va_arg(l, hashfunc_t);
}
va_end(l);
this->nfuncs=nfuncs;
this->asize=size;
this->hash_k=hash_k;
}
// The Destructor
BloomFilter::~BloomFilter() {
/*
delete(this->a);
delete(this->funcs);
delete(this);
*/
}
int BloomFilter::AddToBloom(std::string word){
char t= '1';
int AddFlag; // to know if the element is added successfully
for(int i=0;i<this->hash_k;i++){
AddFlag=Add(word += t);
t++;
}
return AddFlag;
}
int BloomFilter::Add(std::string word){
size_t size = word.size() + 1;
char * buffer = new char[ size ];
strncpy( buffer, word.c_str(), size );
return Add(buffer);
}
int BloomFilter::Add(const char *s)
{
size_t n;
for(n=0; n<this->nfuncs; ++n) {
SETBIT(this->a, this->funcs[n](s)%this->asize);
}
return 0;
}
int BloomFilter::CheckBloom( std::string word){
int CheckFlag;
char t= '1';
for(int i=0;i<this->hash_k;i++){
if(!Check(word += t)) return 0;
t++;
}
return 1;
}
int BloomFilter::Check(std::string word){
size_t size = word.size() + 1;
char * buffer = new char[ size ];
strncpy( buffer, word.c_str(), size );
return Check(buffer);
}
int BloomFilter::Check(const char *s)
{
size_t n;
for(n=0; n< this->nfuncs; ++n) {
if(!(GETBIT(this->a, this->funcs[n](s)%this->asize))) return 0;
}
return 1;
}
//Print information about this object
void BloomFilter::toString(){
/*EV << "[BloomFilter] Hello, I am ready ? " << ready
<<" ; max entry :" << maxEntry << endl;*/
}
What's the fix for this error?
That's a linker, not a C++ compiler error. You will probably have to add the .o file generated from you .cc file to the list of objects that get linked together to form libinet.dylib
I got rid of this error after copying files .cc and .h from my root project to the project I'm working on (in the specified directory).
I did this while running omnet++ and within the projects browser.
I'm not sure how does that link to the "linker" problem but it definitely solved mine.
I have a struct defined in a header file with three other files that #include that header file. One is another header(queue.h) file that defines a very basic hash table and the other two are source codes where one is defining the functions from the hash table header(queue.cpp) and the other contains main(p2.cpp).
The problem that I'm having is that the struct seems to work fine in p2.cpp but in queue.h the compiler is telling me that the struct is undefined.
Here is p2.h containing the struct definition.
#ifndef __P2_H__
#define __P2_H__
#define xCoor 0
#define yCoor 1
#include <iostream>
#include <string>
#include "queue.h"
#include "dlist.h" //linked list which I know works and is not the problem
using namespace std;
struct spot {
float key[2];
string name, category;
};
#endif /* __P2_H__ */
I have queue.h included in this header so that I only have to include p2.h in p2.cpp.
Here is p2.cpp
#include <iostream>
#include <string>
#include <iomanip>
#include "p2.h"
using namespace std;
int main () {
cout << fixed;
cout << setprecision (4);
Queue hashTable;
spot *spot1 = new spot;
spot1->key[xCoor] = 42.2893;
spot1->key[yCoor] = -83.7391;
spot1->name = "NorthsideGrill";
spot1->category = "restaurant";
hashTable.insert(spot1);
Dlist<spot> test = hashTable.find(42.2893, -83.7391);
while (!test.isEmpty()) {
spot *temp = test.removeFront();
cout << temp->key[xCoor] << " " << temp->key[yCoor] << " " << temp->name << " " << temp->category << endl;
delete temp;
}
return 0;
}
Places and item in the hash table and takes it back out.
Here is queue.h
#ifndef __QUEUE_H__
#define __QUEUE_H__
#include <iostream>
#include <string>
#include "dlist.h"
#include "p2.h"
using namespace std;
class Queue {
// OVERVIEW: contains a dynamic array of spaces.
public:
// Operational methods
bool isEmpty();
// EFFECTS: returns true if list is empy, false otherwise
void insert(spot *o);
// MODIFIES this
// EFFECTS inserts o into the array
Dlist<spot> find(float X, float Y);
// Maintenance methods
Queue(); // ctor
~Queue(); // dtor
private:
// A private type
int numInserted;
int maxElts;
Dlist <spot>** queue;
// Utility methods
//Increases the size of the queue.
void makeLarger();
int hashFunc(float X, float Y, int modNum);
};
#endif /* __QUEUE_H__ */
Here is queue.cpp
#include <iostream>
#include <string>
#include <cstdlib>
#include "queue.h"
using namespace std;
bool Queue::isEmpty() {
return !numInserted;
}
void Queue::insert(spot *o) {
if (numInserted >= maxElts) {
makeLarger();
}
int index = hashFunc(o->key[xCoor], o->key[yCoor], maxElts);
queue[index] -> insertFront(o);
}
Queue::Queue() {
numInserted = 0;
maxElts = 1000;
queue = new Dlist<spot>*[maxElts];
for (int i = 0; i < maxElts; i++) {
queue[i] = new Dlist<spot>;
}
}
Queue::~Queue() {
for (int i = 0; i < maxElts; i++) {
delete queue[i];
}
delete[] queue;
}
void Queue::makeLarger() {
Dlist <spot>** temp = queue;
queue = new Dlist <spot>*[maxElts*2];
for (int i = 0; i < maxElts*2; i++) {
queue[i] = new Dlist<spot>;
}
for (int i = 0; i < maxElts; i++) {
while (!temp[i] -> isEmpty()) {
spot *spotTemp = temp[i] -> removeFront();
int index = hashFunc(spotTemp->key[xCoor], spotTemp->key[yCoor], maxElts*2);
queue[index] -> insertFront(spotTemp);
}
}
for (int i = 0; i < maxElts; i++) {
delete temp[i];
}
delete[] temp;
maxElts *= 2;
}
int Queue::hashFunc(float X, float Y, int modNum) {
return ((int)(10000*X) + (int)(10000*Y))%modNum;
}
Dlist<spot> Queue::find(float X, float Y) {
Dlist<spot> result;
Dlist<spot> *temp = new Dlist<spot>;
int index = hashFunc(X, Y, maxElts);
while (!queue[index] -> isEmpty()) {
spot *curSpot = queue[index] -> removeFront();
if ((curSpot->key[xCoor] == X) && (curSpot->key[yCoor] == Y)) {
result.insertFront(new spot(*curSpot));
}
temp -> insertFront(curSpot);
}
delete queue[index];
queue[index] = temp;
return result;
}
I believe that the problem is in my queue.h file because it's where I get all of the errors like "spot has not been declared". Every time spot appears in queue.h I have at least one error. I searched around for anything like this but all I could find was people trying to share one instance of a struct across multiple source files, or the obvious question of putting a struct in a header and including that header across multiple source files(which is what I'm doing but my problem seems to be a rather unique one).
You are including queue.h within the header that actually defines spot, so by the point the file is actually included spot has not been defined yet.
For your scope guards, note that identifiers starting with a double underscore are reserved by the implementation, don't use them.
And this is a poor choice even in plain C:
#define xCoor 0
#define yCoor 1
use this instead:
enum {
xCoor = 0
, yCoor = 1
};
Ok first never ever using "using" clauses in header files (it destroys the purposes of namespaces)
2nd provide a complete example that fails to compile
In addition to what others have said, you also have a circular reference error, which can also lead to similar undefined symbol errors. You have queue.h include p2.h, which includes queue.h.