Linker error [undefined reference to ..]

Hello, this is the first time i post on this forum. I am a beginner in C++. I wrote some code in three files (sales.h, saless.cpp and main.cpp) and when i compile the project (I USE DEVC++ compiler in windows 7 32bit) i get the following errors :

[Linker error] undefined reference to `SALES::setSales(SALES::Sales&, double const*, int)'
[Linker error] undefined reference to `SALES::setSales(SALES::Sales&, double const*, int)'
[Linker error] undefined reference to `SALES::setSales(SALES::Sales&, double const*, int)'
[Linker error] undefined reference to `SALES::setSales(SALES::Sales&, double const*, int)'
ld returned 1 exit status


Here follows my code:

sales.h:

#ifndef SALES_H
#define SALES_H

namespace SALES
{
const int QUARTERS = 4;

struct Sales
{
double sales[QUARTERS];
double average;
double max;
double min;
};

void setSales(Sales & s,const double ar[], int n);

void setSales(Sales & s);

void showSales(const Sales & s);

}

#endif

saless.cpp:

#include <iostream>
#include "sales.h"

using namespace SALES;

void setSales(Sales & s,const double ar[], int n)
{
s.average = 0;
s.max = 0;
s.min = 0;
double sum = 0;

while(s.sales)
{
for(int i=0;i<n;i++)
{s.sales[i] = ar[i];

if(s.sales[i] > s.max)
s.max = s.sales[i];

if(s.sales[i] < s.min)
s.min = s.sales[i];

sum += s.sales[i];
}

}

s.average = sum/n;
}


void setSales(Sales & s)
{
s.average = 0;
s.max = 0;
s.min = 0;
double sum = 0;

std::cout << "Please enter the values of sales for each quarter below\n\n";

for(int i=0;i<4;i++)
{ std::cout << "Quarter #" << i+1 << ": ";
std::cin >> s.sales[i];
std::cout << "\n";

if(s.sales[i] > s.max)
s.max = s.sales[i];

if(s.sales[i] < s.min)
s.min = s.sales[i];

sum += s.sales[i];
}

s.average = sum/4;

};

void showSales(const Sales & s)
{
int size = sizeof(s.sales)/sizeof(double);
for(int i=0;i<size;i++)
{
std::cout << s.sales[i] << "\t";
}

std::cout << "\n Max: " << s.max;
std::cout << "\n Min: " << s.min;
std::cout << "\n Average : " << s.average;
};


main.cpp:

#include <cstdlib>
#include <iostream>
#include "sales.h"


//using namespace sales;

int main()
{

SALES::Sales win;
SALES::Sales mac;

//decalring size of ar[]
int n;
std::cout << "Enter the number of quarters you wish to insert (<=4 OR >0): ";
std::cin >> n;
while(n<=0 || n>4)
{std::cout << "You entered invalid value, please try again!";
std::cin >> n;
}


//constructing ar[]
double ar[n];
std::cout << "Enter the number of sales for each quarter: ";
for(int k=0;k<n;k++)
{std::cout << "\nQuarter #" << k+1 << ": ";
std::cin >> ar[k];
}

//const double sal[n] = ;

//calling functions from saless.cpp
SALES::setSales(win,ar,n);

SALES::setSales(mac);

SALES::showSales(win);
SALES::showSales(mac);

cin.get();
cin.get();

return 0;
}


Thank you for any suggestions!! I just can't find out why I get this error...help :)
1
2
3
4
5
6
7
8
9
10
11
SALES::Sales win;
SALES::Sales mac;

//[...]

SALES::setSales(win,ar,n);

SALES::setSales(mac);

SALES::showSales(win);
SALES::showSales(mac);


"::" is for defining a function that is declared inside a class (the class SALES, in this case). I don't know where did you get it from, but just get rid off it, and it should be fine ;) You just need to #include the header file of your function's declaration (as you already have) and call it simply this way:

1
2
3
4
5
6
7
8
9
10
11
Sales win;
Sales mac;

//[...]

setSales(win,ar,n);

setSales(mac);

showSales(win);
showSales(mac);


In further questions, I suggest you to put your code in "source code" format, then it's a lot easier other people to help!
Last edited on
@JCaselles - wouldn't you use the scope operator (::) also with namespaces. If he wants to use any namespace within his function he can use the scope operator to use such functions i thought, just like std::cout. I may be wrong though.

@murdok - you are linking only the .cpp files right?
You need to define the functions setSales within the namespace SALES. Simply declaring using namespace SALES at the top of the file isn't enough.

saless.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#include <iostream>
#include "sales.h"

using namespace SALES
{
    void setSales(Sales & s,const double ar[], int n)
    {
        s.average = 0;
        s.max = 0;
        s.min = 0;
        double sum = 0;

        while(s.sales)
        {
            for(int i=0;i<n;i++)
            {   s.sales[i] = ar[i];

                if(s.sales[i] > s.max)
                    s.max = s.sales[i];

                if(s.sales[i] < s.min)
                    s.min = s.sales[i];

                sum += s.sales[i];
            }
        }

        s.average = sum/n;
    }

    void setSales(Sales & s)
    {
        s.average = 0;
        s.max = 0;
        s.min = 0;
        double sum = 0;

        std::cout << "Please enter the values of sales for each quarter below\n\n";

        for(int i=0;i<4;i++)
        {  std::cout << "Quarter #" << i+1 << ": ";
            std::cin >> s.sales[i];
            std::cout << "\n";

            if(s.sales[i] > s.max)
                s.max = s.sales[i];

            if(s.sales[i] < s.min)
                s.min = s.sales[i];

            sum += s.sales[i];
        }

        s.average = sum/4;
    }

    void showSales(const Sales & s)
    {
        int size = sizeof(s.sales)/sizeof(double);
        for(int i=0;i<size;i++)
        {
            std::cout << s.sales[i] << "\t";
        }

        std::cout << "\n Max: " << s.max;
        std::cout << "\n Min: " << s.min;
        std::cout << "\n Average : " << s.average;
    }
}
@JCaselles - wouldn't you use the scope operator (::) also with namespaces. If he wants to use any namespace within his function he can use the scope operator to use such functions i thought, just like std::cout. I may be wrong though.


My bad! I didn't realize he's using namespaces! You're right. (Again, next time, you better post your code in it's dedicated format!!! ¬¬ ;)

Now, your problem is sales.cpp. This is the definition file of namespace SALES, therefore you shouldn't "use namespace SALES" but rather still define SALES, since in the header file you've only declared it, like all the functions and variables.

With only this change it should compile (compiles on mine). You have some kind of endless loop, though...

sales.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include "sales.h"

namespace SALES{

void setSales(Sales & s,const double ar[], int n)
{
s.average = 0;
s.max = 0;
s.min = 0;
double sum = 0;

while(s.sales)
{
for(int i=0;i<n;i++)
{s.sales[i] = ar[i];

if(s.sales[i] > s.max)
s.max = s.sales[i];

if(s.sales[i] < s.min)
s.min = s.sales[i];

sum += s.sales[i];
}

}

s.average = sum/n;
}


void setSales(Sales & s)
{
s.average = 0;
s.max = 0;
s.min = 0;
double sum = 0;

std::cout << "Please enter the values of sales for each quarter below\n\n";

for(int i=0;i<4;i++)
{ std::cout << "Quarter #" << i+1 << ": ";
std::cin >> s.sales[i];
std::cout << "\n";

if(s.sales[i] > s.max)
s.max = s.sales[i];

if(s.sales[i] < s.min)
s.min = s.sales[i];

sum += s.sales[i];
}

s.average = sum/4;

};

void showSales(const Sales & s)
{
int size = sizeof(s.sales)/sizeof(double);
for(int i=0;i<size;i++)
{
std::cout << s.sales[i] << "\t";
}

std::cout << "\n Max: " << s.max;
std::cout << "\n Min: " << s.min;
std::cout << "\n Average : " << s.average;
};
}
Last edited on
Sorry, perhaps I'm a little sleepy... How the hell is this compiling?? (it does compile in code::blocks!!)

1
2
//constructing ar[]
double ar[n];


Did I miss something (again)??? shouldn't it be double * ar = new double [n];

BTW, this loop looks pretty ugly...:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
while(s.sales)
{
for(int i=0;i<n;i++)
{s.sales[i] = ar[i];

if(s.sales[i] > s.max)
s.max = s.sales[i];

if(s.sales[i] < s.min)
s.min = s.sales[i];

sum += s.sales[i];
}
} 

why do you even need it? you already have de for loop... (Deleting it solves the endless loop )
Last edited on
Thanks JCaselles, it worked!!
How the hell is this compiling?? (it does compile in code::blocks!!)
1
2
//constructing ar[]
double ar[n];

See: http://www.cplusplus.com/forum/unices/56833/#msg306366
Last edited on
An alternative, in sales.cpp, without reopening the namespace:

1
2
3
4
5
6
7
8
9
void SALES::setSales(Sales & s,const double ar[], int n)
{
     // ...
}

void SALES::setSales(Sales & s)
{
     // ...
}


How the hell is this compiling?? (it does compile in code::blocks!!)
1
2
//constructing ar[]
double ar[n];


See: http://www.cplusplus.com/forum/unices/56833/#msg306366


Thanks man. Though, I still don't find the sense to that... Will it manage the dynamic memory well, like a vector, or you're just writing crappy code?
Last edited on
Topic archived. No new replies allowed.