#1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    32
    Rep Power
    11

    I'm getting an "undefined reference" error using functions


    I'm working on another script and I'm getting this error. Not sure what's causing it or how to fix it. I've gone through and changed so many things trying to fix it and I've run out of ideas.

    I'm pretty new to c++ (a few weeks) so this could be something really easy but I just can't figure it out. This is my first attempt at actually using more than 1 function.

    Here's the error.
    [Linker error] undefined reference to 'calcNetpay(float, float, float)'

    And here's the code. I'm sorry for posting all the code but it didn't give me a line number for the error so I wasn't sure what to post.

    Thanks in advance.

    PHP Code:
    #include <iostream>
    #include <string>

    using namespace std;

    //function prototypes
    void getInput(string&, float&);
    void calcNetpay(floatfloatfloat);
    void calcFedTaxes(floatfloatfloatfloatfloat);
    void displayInfo(stringfloatfloatfloat);


    int main()
    {    
        const 
    float FWT_RATE   float(.2);
        const 
    float FICA_RATE float(.08);
        
        
    string name   "";
        
    float salary  0.0;
        
    float fwtTax  0.0
        
    float ficaTax 0.0;
        
    float netPay  0.0;
        
    float FWT     0.0;
        
    float FICA    0.0;
        
        
    //enter input items
        
    getInput(namesalary);
        
        
    //Calculate Taxes
         
    calcFedTaxes(salaryFICAFWTFWT_RATEFICA_RATE);
         
         
    //Calculate Net Pay
         
    calcNetpay(salaryFWTFICA);
         
         
    //display name, gross, taxes, and net
         
    displayInfo(nameFWTFICAnetPay);
         
        
    /* 
        FWT = (salary * FWT_RATE); 
        FICA = (salary * FICA_RATE);
         */ 
        
        
        /* 
        cout << "Employee Name: " << name << endl;
        cout << "Federal Withholding: " << FWT << endl;
        cout << "Federal insurance: " << FICA << endl;
        cout << "Weekly Net Pay: " << netPay << endl;
        */
        

    }
        
    //end of main function
        //*****program-defined functions*****

    void calcNetpay (float salaryfloat FWTfloat FICAfloat netPay)
        {
        
    netPay salary-(FWT+FICA);
        }

    void getInput (string &namefloat &salary)
        {
        
    cout << "Enter your name: ";
        
    cout << endl;
        
    cin >> name;
        
    cout << endl;
        
    cout << endl;
        
    cout << "Enter Weekly Salary: ";
        
    cout << endl;
        
    cin >> salary;
        
    cout << endl;
        
    cout << endl;
        }

    void calcFedTaxes (float salaryfloat FICAfloat FWTfloat FWT_RATEfloat FICA_RATE)
        {
        
    FWT salary FWT_RATE
        
    FICA salary FICA_RATE;
        }
        
    void displayInfo (string namefloat FWTfloat FICAfloat netPay)
        {
        
    cout << "Employee Name: " << name << endl;
        
    cout << "Federal Withholding: " << FWT << endl;
        
    cout << "Federal insurance: " << FICA << endl;
        
    cout << "Weekly Net Pay: " << netPay << endl;
        } 
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    You declared calcNetpay as having three float arguments and you call it with three arguments, but your implementation has four float arguments. The linker cannot find the implementation of calcNetpay that has three float arguments.

    Also, if you intended the calculated value to be returned through the fourth argument, then you need to make it a reference. Otherwise, even if you called it with a fourth argument, that fourth argument's value would never change.

    How I think it should be:
    Code:
    void calcNetpay (float salary, float FWT, float FICA, float &netPay)
    {
        netPay = salary-(FWT+FICA);
    }
    Last edited by dwise1_aol; August 21st, 2003 at 05:57 PM.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    32
    Rep Power
    11
    Thanks for the quick reply!

    Ok, here are the thing's I've changed from the existing code.

    PHP Code:
    //Calculate Net Pay
         
    calcNetpay(salaryFWTFICAnetPay); 
    and I changed the calcNetpay to how you suggested. Now what happens is it errors out on lines 8 and 33.

    line 8
    PHP Code:
    void calcNetpay(floatfloatfloat); 
    line 33
    PHP Code:
    calcNetpay(salaryFWTFICAnetPay); 
    I'm not sure how to explain the error message. For line 8 it just says "too" and for line 33 it says "at". I'll try to show you what it looks like...


    /Documents and settings | In
    8 | too
    33 | at


    Any ideas?
  6. #4
  7. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    OK, now when you call the function, it doesn't know what you are talking about. The prototype (on line 8) has to match the implementation (line 56 est.) and the function call (line 33) has to have the same number of arguments of the same or compatible data types.

    Before you call a function, you need to have provided the compiler with a description of that function, which is accomplished with the function prototype. Your function prototype only has three arguments, so when you call it, it has no idea what to do about that fourth argument you've thrown at it. BTW, if you don't provide a data type, then the compiler automatically assumes int; that feature is a throw-back to the earliest days of C, back when we were still punching holes into cards.

    BTW, in C++, you can overload a function name; i.e., have multiple functions with the same name, just so long as the argument lists are different so the compiler can tell them apart and match each function call up with the correct function. Part of what's happening here is that it looks like you're overloading the function, but you aren't providing any prototype for the 4-argument version nor any implementation for the 3-argument version (which the compiler doesn't complain about since you aren't calling that one).

    Solution: change the prototype on line 8 to 4 floats.
    Last edited by dwise1_aol; August 21st, 2003 at 07:38 PM.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    32
    Rep Power
    11
    Thanks a lot for helping out.

    I changed the prototype on line 8 to 4 floats, but now I'm back to the
    PHP Code:
    [Linker errorundefined reference to 'calcNetpay(float, float, float, float)' 
    Could this be a compiler issue? Or do I still have something wrong?
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    Originally posted by dcj1978
    Thanks a lot for helping out.

    I changed the prototype on line 8 to 4 floats, but now I'm back to the
    PHP Code:
    [Linker errorundefined reference to 'calcNetpay(float, float, float, float)' 
    Could this be a compiler issue? Or do I still have something wrong?
    In the implementation of that function, had you also changed the fourth argument to a float& as I had suggested? If so, then that would be a different type than a float.

    To provide the prototype, just copy the function header from the function implementation and paste it at the top of the file -- ie, replace the current prototype with this copy. Be sure to add a semicolon to the end of the line. If that doesn't work, then there is something strange going on.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    32
    Rep Power
    11
    Oh. Sorry. I missed the "&".. fixed that and it's compiling now. Thanks for your help.

    If you feel like helping me out with one more problem, thatd be great. If not, it's cool. You've already helped me quite a bit.

    It's not displaying any data from these 2 lines..
    PHP Code:
    cout << "Federal Withholding: " << FWT << endl;
        
    cout << "Federal insurance: " << FICA << endl
    The code has changed a bit so, here's the revised version... since the whole thing seems to be tied together..again, i'm posting the entire thing.

    PHP Code:
    #include <iostream>
    #include <string>

    using namespace std;

    //function prototypes
    void getInput(string&, float&);
    void calcNetpay(floatfloatfloatfloat&);
    void calcFedTaxes(floatfloatfloatfloatfloat);
    void displayInfo(stringfloatfloatfloat);


    int main()
    {    
        const 
    float FWT_RATE   float(.2);
        const 
    float FICA_RATE float(.08);
        
        
    string name   "";
        
    float salary  0.0;
        
    float fwtTax  0.0
        
    float ficaTax 0.0;
        
    float netPay  0.0;
        
    float FWT     0.0;
        
    float FICA    0.0;
        
        
    //enter input items
        
    getInput(namesalary);
        
        
    //Calculate Taxes
         
    calcFedTaxes(salaryFICAFWTFWT_RATEFICA_RATE);
         
         
    //Calculate Net Pay
         
    calcNetpay(salaryFWTFICAnetPay);
         
         
    //display name, gross, taxes, and net
         
    displayInfo(nameFWTFICAnetPay);
         
        
    /* 
        FWT = (salary * FWT_RATE); 
        FICA = (salary * FICA_RATE);
         */ 
        
        
        /* 
        cout << "Employee Name: " << name << endl;
        cout << "Federal Withholding: " << FWT << endl;
        cout << "Federal insurance: " << FICA << endl;
        cout << "Weekly Net Pay: " << netPay << endl;
        */
        

    }
        
    //end of main function
        //*****program-defined functions*****

    void calcNetpay (float salaryfloat FWTfloat FICAfloat &netPay)
    {
        
    netPay salary-(FWT+FICA);
    }

    void getInput (string &namefloat &salary)
        {
        
    cout << "Enter your name: ";
        
    cout << endl;
        
    cin >> name;
        
    cout << endl;
        
    cout << endl;
        
    cout << "Enter Weekly Salary: ";
        
    cout << endl;
        
    cin >> salary;
        
    cout << endl;
        
    cout << endl;
        }

    void calcFedTaxes (float salaryfloat FICAfloat FWTfloat FWT_RATEfloat FICA_RATE)
        {    
        
    FWT = (salary FWT_RATE); 
        
    FICA = (salary FICA_RATE);
        }
        
    void displayInfo (string namefloat FWTfloat FICAfloat netPay)
        {
        
    cout << "Employee Name: " << name << endl;
        
    cout << "Federal Withholding: " << FWT << endl;
        
    cout << "Federal insurance: " << FICA << endl;
        
    cout << "Weekly Net Pay: " << netPay << endl;
        } 
    Thanks in advance. And again, thanks for your help already.
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,091
    Rep Power
    2222
    OK, by "not displaying any data", I assume that you mean that those two lines print out:
    Federal Withholding: 0.0
    Federal insurance: 0.0
    The reason is because those calculated values are never getting out of the calcFedTaxes function. It's the old call-by-value/call-by-reference trick.

    This is an extremely important concept both in C and in C++, so I'll take a bit of time to explain it.

    When you call a function, temporary storage is created for the function's local variables and for its arguments. Before the function's code is run, that local storage for the arguments is loaded with the values that you passed when you made the call. By default, C and C++ always load the value of an argument. This is called "call by value". The function can then use that value and it can make changes to the temporary memory location containing that value, but none of those changes will ever leave the function -- the variable whose value was passed in the function call will never be affected by those changes.

    Of course, there are times, like in your program, where you want to change the variable you are passing; that is accomplished by using "call by reference" (AKA "call by name"). In C, the standard way to do call-by-reference is to pass the address of the variable you want to change and the function body then uses pointer notation to effect those changes.

    C++ also uses pointers and pointer notation, but it also has a cleaner notation using "references". That is what that '&' is about in the function's argument list. It does the same thing as passing a pointer, except you don't have to mess with pointer notation.

    You need to train yourself to think about whether you want to return changes through the argument list and to then use references in those cases.

    Your function prototype and header should look like this:
    Code:
    void calcFedTaxes (float salary, float &FICA, float &FWT, float FWT_RATE, float FICA_RATE)
    Be sure that the function prototype contains the same changes.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2003
    Posts
    32
    Rep Power
    11
    Wow. Thanks for the great reply. It helps a lot. I'll get a hang of this thing sooner or later.

    Thanks again!

IMN logo majestic logo threadwatch logo seochat tools logo