Search code examples
cheaderundefined

Undefined reference to a function defined in a header file in C


This may seem a question already asked but I

  • found no specific info about my case, e.g. there was something that I've already done
  • fail to compile a program properly despite including all files and writing a hopefully normal header files and including them wherever I need them

My code in app.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "adding_tasks.h"
#include "viewing_tasks.h"
#include "removing_tasks.h"
#include "completing_tasks.h"
#include "buffer_cleaning.h"

int main()
{   
...
return 0;
}

My code from completing_tasks.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "buffer_cleaning.h"
#include "completing_tasks.h"

void task_complete(char ***all_tasks, int *num_tasks)
{
...
}

My completing_tasks.h just to ensure it is done properly and I'm not blind:

#ifndef COMPLETING_TASKS_H
#define COMPLETING_TASKS_H

void task_complete(char ***all_tasks, int *num_tasks);

#endif

The traceback I get:

app.c:(.text+0x6d): undefined reference to `clear_input_buffer'
/usr/bin/ld: app.c:(.text+0x88): undefined reference to `update_task_list'
/usr/bin/ld: app.c:(.text+0xa8): undefined reference to `task_view'
/usr/bin/ld: app.c:(.text+0xc8): undefined reference to `task_remove'
/usr/bin/ld: app.c:(.text+0xe5): undefined reference to `task_complete'
collect2: error: ld returned 1 exit status

The way I compile it all:

gcc -o app app.c adding_tasks.c completing_tasks.c removing_tasks.c buffer_cleaning.c

There go the questions:

  • Do I have any obvious mistakes that make me look like a fool here?
  • If not, what is the reason of such behaviour?
  • Can this stem from recursion with buffer_cleaning.h? If so, what do I do to prevent it if I need it in all of these files?
  • How can I improve the code so that it perhaps might start working or at least giving me another error?

I am ready to provide more code snippets if needed.


Solution

  • Those functions are not defined in the header, they are merely declared in the header.

    The declaration satisfies the compiler, so the translation unit compiles without error. However these are linker errors. The linker resolves references between separately compiled translation units.

    Given your stated GCC command line it is not clear at least why task_complete is not resolved (the only undefined symbol for which you provided the source (albeit elided). However we have only your word for it that that is the command line that resulted in those errors. You should post the entire build log, not just the errors.

    Do I have any obvious mistakes that make me look like a fool here?

    Apart from not spotting that these are linker errors, so the code must have compiled, no, but you have not provided all the diagnostic information provided. Provide the complete log from the GCC command line to the ld returned 1 exit. Also add -Wall -Werror to your GCC command line.

    If not, what is the reason of such behaviour?

    As explained above - they are linker errors. Something is wrong with your link. Either the command line is not as stated, or the listed translation units do not contain the stated code. Have you saved the files for example.

    Can this stem from recursion with buffer_cleaning.h?

    Not since you have linker rather than compiler or pre-processor errors no.

    If so, what do I do to prevent it if I need it in all of these files?

    Not the problem.

    How can I improve the code so that it perhaps might start working or at least giving me another error?

    It is a linker issue, not a code issue. You have to successfully link the listed modules and those modules must contain the stated symbol definitions.