Linker Error Help!!

Discussion in 'C++' started by Joey Bork Dugan, Apr 18, 2012.

  1. 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()
     
    Joey Bork Dugan, Apr 18, 2012
    #1
    1. Advertising

  2. Joey Bork Dugan

    Ian Collins Guest

    On 04/18/12 11:50 AM, Joey Bork Dugan wrote:

    > bool pcheck(int,int);


    Here you declare pcheck with two int parameters.

    <snip>

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


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

    --
    Ian Collins
     
    Ian Collins, Apr 18, 2012
    #2
    1. Advertising

  3. 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:

    On Apr 17, 4:50 pm, Joey Bork Dugan <> wrote:
    > 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
     
    Kevin McCarty, Apr 18, 2012
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Wolfgang Rueckert

    Linker error - unsolved external symbol

    Wolfgang Rueckert, Jun 30, 2003, in forum: C++
    Replies:
    0
    Views:
    740
    Wolfgang Rueckert
    Jun 30, 2003
  2. TR
    Replies:
    3
    Views:
    8,203
    New_user
    Jun 10, 2004
  3. Replies:
    1
    Views:
    353
  4. quad
    Replies:
    3
    Views:
    2,367
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=
    Jun 9, 2007
  5. lashnjo
    Replies:
    1
    Views:
    440
    Robert Bauck Hamar
    Jul 3, 2007
Loading...

Share This Page