Linker Error Help!!

J

Joey Bork Dugan

I'm a beginner C++ programmer and I'm having an issue with a Linker
Error. I keep getting the following:

[Linker error] undefined reference to `pcheck(int, int)'
ld returned 1 exit status

I've been staring at it for HOURS and I can't figure it out! Help
please?

Below is my code:

#include <iostream> //to use input and output
#include <iomanip> //to use fixed, set precision
#include <fstream> //to input/output files
using namespace std; //to use standard c++ functions

int batch9[20][4]={0};
long double volumes[20]={0};
double Vhats=(3.14*(10*10)*10),Vboots=(8*10*18),Vcanes=(.5*7*7*12);
long double TVhats,TVboots,TVcanes,x;
int set;
bool fcheck, fits[20];
bool filecheck();
bool fitcheck(long double);
bool pcheck(int,int);

int main(){ //beginning program

cout<<"Integrated Project Console"<<endl;

fcheck=filecheck();

if (fcheck==false){ //Tests to see if file
was open
cout<<"File not opened!"<<endl<<endl; //Returned if file is
not opened
system("pause");
return 0;
}//end if
else {
cout<<"File opened successfully!"<<endl<<endl; //Returned if file
is opened
}//end else

Vhats=Vhats+(Vhats*.12);
Vboots+=(Vboots*.12);
Vcanes+=(Vcanes*.12);

ifstream infile;
infile.open("Batch_09.txt");

for (int a=0;a<20;a++){
for (int b=0;b<4;b++){
infile>>batch9[a]; //Creates 2D Matrix from
the file
}//end loop b
}//end loop a

cout<<fixed<<setprecision(2);
cout<<setw(10)<<"Set #"<<setw(6)<<"Hats"<<setw(6)<<"Boots";
cout<<setw(14)<<"Shillelaghs"<<endl;

for (int c=0;c<20;c++){
for (int d=0;d<4;d++){
cout<<setw(6)<<batch9[c][d]<<" ";
}//end loop d
cout<<endl;
}//end loop c

for (set=0;set<20;set++){
if (pcheck(set,batch9[20][4])==false){
volumes[set]=3000000;
}//end if
else {
TVhats = batch9[set][1]*Vhats;
TVboots = batch9[set][2]*Vboots;
TVcanes = batch9[set][3]*Vcanes;
volumes[set]=TVhats+TVboots+TVcanes;
}//end else
}//end for

for (set=0;set<20;set++){
x=volumes[set];
if (fitcheck(x)==true){
fits[set]=true;
}
else {
fits[set]=false;
}
}

for (int a=0;a<20;a++){
if (fits[a]==true){
cout<<"Set "<<a+1<<" fits"<<endl;
}
else if (fits[a]==false){
cout<<"Set "<<a+1<<" does not fit"<<endl;
}
}

cout<<endl;
system("pause");
return 0;
}//end main()

//
================================PERCENTCHECK==================================
bool pcheck(int set,int batch9[20][4]){

int x=batch9[set][1];
int y=batch9[set][2];
int z=batch9[set][3];

int items=x+y+z;
int Pitems = items/10;
if (x<Pitems||y<Pitems||z<Pitems){
return false;
}//end if
else{
return true;
}//end else
}//end percentcheck()

//
================================FITCHECK======================================

bool fitcheck(long double x){
long double container=(1320*(12*12*12));

if (x<=container){
return true;
}//end if
else {
return false;
}//end else
}//end fitcheck()
//
================================FILECHECK=====================================

bool filecheck(){
ifstream infile;
infile.open("Batch_09.txt"); //Opens File
if (!infile){ //Tests to see if file was
open
return false;
}//end if
else {
return true;
}//end else
}//end filecheck()
 
I

Ian Collins

bool pcheck(int,int);

Here you declare pcheck with two int parameters.

================================PERCENTCHECK==================================
bool pcheck(int set,int batch9[20][4]){

Here you define it with an int and an int[][] parameter.
 
K

Kevin McCarty

Hello,

Your chief problem causing linker errors is that, as Ian Collins
pointed out, your declaration of pcheck() in the file where you define
main() does not match the definition of pcheck() in the file where it
is defined.

Below I add some other tips:

I'm a beginner C++ programmer and I'm having an issue with a Linker
Error.  I keep getting the following:

[Linker error] undefined reference to `pcheck(int, int)'
ld returned 1 exit status

I've been staring at it for HOURS and I can't figure it out! Help
please?

Below is my code:


Below you are declaring a whole bunch of variables as globals ... this
is generally a bad practice, it's better to declare them inside a
function (main(), in this case).
int batch9[20][4]={0};
long double volumes[20]={0};

Here, and in the rest of the program, you are using "magic
numbers" ... there is no indication of why you are multiplying
3.14*10*10*10, addding Vhats*.12 to Vhats below, etc. Consider using
const variables with evocative names.

The use of variables with the type 'long double' is unusual and
probably not necessary in your code, given that you are only using a
precision of three decimal places otherwise. Generally a simple
'double' is the best choice for numeric operations (an IEEE 8-byte
double has a precision of 1 part in 10^16, which will certainly more
than suffice for you). Be aware that in some compilers, Microsoft's
among them, 'long double' does not even have any more additional
precision than 'double'.

double Vhats=(3.14*(10*10)*10),Vboots=(8*10*18),Vcanes=(.5*7*7*12);
long double TVhats,TVboots,TVcanes,x;
int set;
bool fcheck, fits[20];
bool filecheck();
bool fitcheck(long double);
bool pcheck(int,int);

As mentioned, the above declaration should be:

bool pcheck(int, int [20][4]);


int main(){                     //beginning program

cout<<"Integrated Project Console"<<endl;

fcheck=filecheck();

if (fcheck==false){                             //Tests to see if file
was open
     cout<<"File not opened!"<<endl<<endl;      //Returned iffile is
not opened
     system("pause");
     return 0;
     }//end if
else {
     cout<<"File opened successfully!"<<endl<<endl; //Returned if file
is opened
     }//end else

Vhats=Vhats+(Vhats*.12);
Vboots+=(Vboots*.12);
Vcanes+=(Vcanes*.12);

Easier to multiply by 1.12, e.g.,

Vhats *= 1.12;

ifstream infile;
infile.open("Batch_09.txt");

The need for the function filecheck() isn't really clear to me. You
have to open the file here, anyway, so the small amount of code in
filecheck() might as well be here in main(). As it stands, your code
risks getting out of sync because you need to make sure to use the
same filename "Batch_09.txt" both in main() and in filecheck(). If
you had to change it in one place, there would be a risk of forgetting
to do so in the other. If filecheck() is needed, it would be best for
it to take a string parameter to specify the filename.

for (int a=0;a<20;a++){
    for (int b=0;b<4;b++){
        infile>>batch9[a];              //Creates 2D Matrix from
the file
        }//end loop b
    }//end loop a

cout<<fixed<<setprecision(2);
cout<<setw(10)<<"Set #"<<setw(6)<<"Hats"<<setw(6)<<"Boots";
cout<<setw(14)<<"Shillelaghs"<<endl;

for (int c=0;c<20;c++){
    for (int d=0;d<4;d++){
        cout<<setw(6)<<batch9[c][d]<<" ";
        }//end loop d
        cout<<endl;
    }//end loop c

for (set=0;set<20;set++){
    if (pcheck(set,batch9[20][4])==false){


Above, I think you intended to pass the entire 20x4 matrix into
pcheck():

if (pcheck(set, batch9) == false)) {

Also, explicit comparisons to a boolean constant are generally non-
idiomatic, although some folks will defend them in some cases. But
most people would write the above as:

if (! pcheck(set, batch9)) {


       volumes[set]=3000000;
       }//end if
    else {
    TVhats = batch9[set][1]*Vhats;
    TVboots = batch9[set][2]*Vboots;
    TVcanes = batch9[set][3]*Vcanes;
    volumes[set]=TVhats+TVboots+TVcanes;
    }//end else

}//end for

for (set=0;set<20;set++){
    x=volumes[set];
    if (fitcheck(x)==true){
       fits[set]=true;
    }
    else {
       fits[set]=false;
    }

The above code block is pretty redundant, you could condense it as:

for (set = 0; set < 20; set++) {
fits[set] = fitcheck(volumes[set]);
}


}

for (int a=0;a<20;a++){
    if (fits[a]==true){
        cout<<"Set "<<a+1<<" fits"<<endl;
    }
    else if (fits[a]==false){
         cout<<"Set "<<a+1<<" does not fit"<<endl;
    }

Again, above it is not idiomatic to test for equality to a boolean
constant. And the "else if" is better as an "else", since there is no
possible value for fits[a] other than true or false:

for (int a = 0; a < 20; a++) {
if (fits[a])
cout << "Set " << a + 1 << " fits" << endl;
else
cout << "Set " << a + 1 << " does not fit" << endl;
}


}

    cout<<endl;
    system("pause");

Be aware that any use of system() is a sign of platform-dependent
code, since the argument passed into system() is by definition
platform-dependent. This code would fail on most systems other than
Windows. This isn't necessarily bad in all cases; most likely you
have no intention of trying to do so, and sometimes platform-dependent
code is the best way to accomplish something; but you should know of
it.

    return 0;

}//end main()

//
================================PERCENTCHECK==================================
bool pcheck(int set,int batch9[20][4]){

int x=batch9[set][1];
int y=batch9[set][2];
int z=batch9[set][3];

int items=x+y+z;
int Pitems = items/10;
if (x<Pitems||y<Pitems||z<Pitems){
   return false;
   }//end if
else{
   return true;
   }//end else

Above, rather than having the if block, you can just return the
inverse of the value of what the if condition is testing:

return ! (x < Pitems || y < Pitems || z < Pitems);

although it's more legible to apply the ! sign through the || [recall
from basic boolean logic that !(a || b) is the same as (!a && !b)], to
better illustrate the actual requirement of the code:

return x >= Pitems && y >= Pitems && z >= Pitems;


}//end percentcheck()

//
================================FITCHECK======================================

bool fitcheck(long double x){
     long double container=(1320*(12*12*12));

Another magic number here!
     if (x<=container){
        return true;
        }//end if
     else {
        return false;
        }//end else}//end fitcheck()


Again, the above if/else can be rewritten in a much simpler format:

return x <= container;

Because this fitcheck() function, too, is very simple, it would
probably make your code more easily readable if you just wrote the
above in the place where fitcheck() is used. Above, I had rewritten
that part of main() as:

for (set = 0; set < 20; set++) {
fits[set] = fitcheck(volumes[set]);
}

so that code in main() would instead become

const long double container = (1320*(12*12*12));
for (set = 0; set < 20; set++) {
fits[set] = (volumes[set] <= container);
}


I hope that at least some of the suggestions above are useful for you.

Best regards,
- Kevin B. McCarty
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top