Thread: Help with error: undefined reference to (function I defined)

  1. #1
    Registered User
    Join Date
    Mar 2011

    Help with error: undefined reference to (function I defined)

    I am new to C programming (taking it as a class) and this forum. I have read homework policy. I've done most of the work for my current assignment but I am stuck with a error that won't go away. I've tried several fixes myself but nothing fixes it. I wrote it without the function and it worked perfectly, then inserted the function 'payroll()', moved the sprintf() line (which works) into it. Can someone tell me what I'm doing wrong? (I need a quick response.)
    The assignment states:
    "Write a C program that accepts as input from the keyboard a floating
    point number, an integer, and a character. Each of these inputs should be
    preceded by a prompt and stored using individual variable names.
    Have your program call a function that assembles the input data into a single
    string. Display the assembled string using the puts() call back in main after
    the function has completed. "
    The error refers to the line where I call the function payroll() and pass the variables to it. I'm using C-Free Standard for my compiler and the error is this:
    [Error] C:\Program Files\C-Free Standard\temp\Untitled4.cpp:28: undefined reference to `payroll(int, char, float, char)'.
    My code is below:
    #include <stdio.h>     /*include standard input/output library*/
    #include <string.h>    /*include string library*/
    #define NSIZE 21       /*define the max name size*/
    char name [NSIZE]={0};     /*declare character string variable name */
    int empID;	            /*declare integer variable empID*/
    float hours;	            /*declare float variable hours*/
    char timeCard [51]={0};     /*declare character string variable timeCard */
    char payroll(int, char, float, char);     /*function prototype for payroll()*/
    int main()	     /*call main()*/
    {	    /*begin main()*/
         printf("Enter employee's id number:  ");     /*prompt user for id input*/
         scanf("%d", &empID);     /*get empID from keyboard*/
         printf("\nEnter employee's name (LAST,First) with no spaces):  ");      /*prompt user for name input*/
         scanf("%s", name);	/*get empID from keyboard*/
         printf("\nEnter hours:  ");       /*prompt user for hours input*/
         scanf("%f", &hours);    /*get hours from keyboard*/
         payroll (empID, name[NSIZE], hours, timeCard [51]);  /* call function*/
         printf("\n\nTime card entry is:");        /*line to inform user */
         puts(timeCard);	/*use display string timeCard compiled in payroll() */ 
         printf("\n\n");  /* line breaks (x3) */
         return 0;     /* return control */
    }	        /* end main */
    char payroll (int empID, char name[NSIZE], float hours, char timeCard [51] )      /*function header for payroll()*/
    {           /* begin payroll() */
         sprintf(timeCard, "%d/%s/%4.2f hrs", empID, name, hours);      /* all variables printed into timeCard string */
         return (timeCard [51]);	/*order function payroll() to return the string timeCard to calling function*/
    }	/*end payroll()*/

  2. #2
    THANK YOU KINDLY SIR Phenax's Avatar
    Join Date
    Mar 2011
    • Don't use global variables if you don't have to. If you are passing your variable as an argument, you should probably just declare it in main.
    • Your function prototype is different than your actual function (char is not char * or char[]!). You need to read up on how to use/declare/pass Character Arrays (C Strings) and probably a little primer on pointers.
    Last edited by Phenax; 03-06-2011 at 10:59 PM.
    Quote Originally Posted by Plato
    Never discourage anyone...who continually makes progress, no matter how slow.

  3. #3
    Registered User
    Join Date
    Mar 2011
    Now I'm totally confused. Between my post and yours, I changed nothing except to save the program, inpreparation to moving on to my next homework problem. and I ran it one more time and got 2 different errors:
    [Error] :39: conflicting types for `payroll'
    [Error] 15: previous declaration of `payroll'

    Why did it change (after 30 or 40 ideations of the function lines, when it kept saying undefined reference to `payroll(int, char, float, char)')

    Then read through the thing you first posted "Cstrings( pointer vs arrays)". I understand arrays and I understand strings (though the point of this assignment was working with them), I understand functions (at least how to set up prototype, function definition, and calling it), I'm not too good with pointers though.

    Then I looked at what you posted (I guess you editted it?) again. I am aware that char * would be a pointer, but char[] being different from char was news to me. So I put into my function prototype (at the char's) char[].
    That resulted in 2 warnings that say:
    [Warning] passing arg 2 of `payroll' makes pointer from integer without a cast."
    (the second one replaces arg 2 with arg 4 but is otherwise identical.)
    And the program runs to gather the inputs but gives me an error window after that.

    I ran it a couple times without changing anything (operational definition of insanity!) The warnings went away, but running the program ran the same (stopping).
    I changed the prototype to char[NSIZE] and char[51]. The warnings came back exactly as before then disappeared as before. Program ran same.

    Removing the [] from the prototype resulted in the return of the 2 Error messages I listed above in this reply.

    Can you or anyone tell me what is going on? Why did my original error go away only to be replaced by two new ones if I didn't change anything? And more importantly, how do I fix this?
    I've been stuck on it for about a week!!

  4. #4
    THANK YOU KINDLY SIR Phenax's Avatar
    Join Date
    Mar 2011
    A "char" is one character. I.e., 'a' or 'b' or 'c' or ';'

    A character array is the same thing as a string. It's an array of characters.
    A pointer to a character is almost the same thing as a character array.

    When you have an array. array[1] just means go to the memory address of array[0] and go to the memory address 1 <unit (int/char/etc)> ahead of that. So a pointer just means it points to a memory address. Thus if you have a pointer, you could do pointer[1] and it'd work fine.
    In fact, when you pass an array as an argument, it is technically "decayed" to a pointer. There are a few differences between an array and a pointer (like what sizeof returns, or what you get when you type in the variable with no index).

    As for your error, the latest one you posted is the "correct" error, or rather the one I got, and the one I expected. Also, I removed the link because it had a few C++ specific things, although the concept remains the same. Just didn't really want to explain what "cout" or "new" or "delete" was.

    First of all, when you call a function, do not put the argument as timeCard[51]. Just use timeCard. If you use timeCard[51], it thinks you're giving it the 51st character of timeCard. The function declaration knows it's of length 51. If you pass timeCard[51] thats a char not a char[], thus the compiler will give you a warning.

    Second of all, fix your variables (they should not be global!). This isn't an error, it's just bad technique.

    Notice how I changed your function prototype to character arrays instead of characters. If you are unsure of what to use for your function prototype, you can just copy and paste the function declaration and add a semicolon. For example:
    char payroll (int empID, char name[NSIZE], float hours, char timeCard[51] );
    is a valid function prototype!

    This seems to be valid code.
    #include <stdio.h>
    #include <string.h>
    #define NSIZE 21
    char payroll(int, char[], float, char[]);
    int main()
    	char name[NSIZE];
    	int empID;
    	float hours;
    	char timeCard[51];
    	printf("Enter employee's id number:  ");
    	scanf("%d", &empID);
    	printf("\nEnter employee's name (LAST,First) with no spaces):  ");
    	scanf("%s", name);
    	printf("\nEnter hours:  ");
    	scanf("%f", &hours);
    	payroll (empID, name, hours, timeCard);
    	printf("\n\nTime card entry is: ");
    	return 0;
    char payroll (int empID, char name[NSIZE], float hours, char timeCard[51] )
    	sprintf(timeCard, "%d/%s/%4.2f hrs", empID, name, hours);
    	return (timeCard[51]);
    Last edited by Phenax; 03-07-2011 at 12:10 AM.
    Quote Originally Posted by Plato
    Never discourage anyone...who continually makes progress, no matter how slow.

  5. #5
    Registered User
    Join Date
    Mar 2011

    Thank you, thank you, thank you.

    1st for the clarification of the char versus char[] and for the clarification of using timeCard versus timeCard[51]. I missed that in my studies somehow. Maybe it just didn't stick.

    2nd for fix, I took what you said the first time, but since still had the calling line jacked it wasn't working. It works now. I put that stuff in there when I was tiptoeing through the program (like a bull in a china shop). I was repeatedly receiving errors that said such and such 'lacked a cast'. I figured out putting the [NSIZE] and [51] worked to remove those errors..

    3rd for the hint on the variables. I've moved them inside of main(). My textbook mentions that too.
    It was a defensive move on my part, to avoid using pointers with functions.
    I've had such a hard time with that in past lessons, something just doesn't work in my mind. I think I can actually formulate it into a question now. How is it, when I pass variables to the function (in the calling line) I can change the names of the variables in the function and pass info back, and it still works? Then how does the whole pointer thing work into it? I'm sure I'll gather more understanding as I work though it more and more.

    I'm still confused by the original error I started with "undefined reference to" (why was I getting it, and why did it go away?)

    Thanks again for your help.

  6. #6
    THANK YOU KINDLY SIR Phenax's Avatar
    Join Date
    Mar 2011
    If you pass a regular variable (non-pointer or array) to a function, it creates a duplicate of that variable. And you are working with an all-new duplicate of your variable. At the end of the function you'd return the value and assign the result of your function to a variable.
    If you pass a pointer (or array) to the function, you are actually modifying that variable. Because it points to the memory address of that variable, and didn't create a duplicate. You of course don't need to return anything here, and people generally use void or int as their function type (int if they want to return whether the function executed properly or not, for example).

    The name of these behaviors is "Pass by value" - which is what you are probably used to. But when you pass a pointer (or an array, because it decays to a pointer), you are "passing by reference" - meaning you are passing a reference to the variable, or directly modifying that variable rather than creating a duplicate. Generally when passing by value, you return the value of the duplicate, and then assign that to a variable. Some languages use pass by value, some languages use pass by reference, some can use either (Like C), although some languages use different function passing systems altogether.

    An array is just a pointer for the most part, and if you pass an array to a function it decays to a pointer anyway. Just try changing your function prototype to (char *) instead of char[]. It'll still work the same, because it's the same thing as far as C's concerned.

    In your payroll function, you don't even need that return. You could change the return type to void and erase the return line and it'd still work (in fact, you probably should). Because you are modifying the actual variable. You passed it's memory address, and are directly modifying that. If you wanted to make a new variable in that function, and return that (unnecessary), you'd have to do
    timecard = payroll (empID, name, hours, timeCard);
    instead of
    payroll (empID, name, hours, timeCard);
    Last edited by Phenax; 03-07-2011 at 01:48 AM.
    Quote Originally Posted by Plato
    Never discourage anyone...who continually makes progress, no matter how slow.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 10
    Last Post: 08-18-2009, 10:21 AM
  2. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  3. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  4. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM

Tags for this Thread