Search code examples
cmacrosexitstatusfactorial

Why is using a macro in my code causing an error and how can I fix it?


I wrote this code:

#include <stdio.h>

#define fctrl(N) ( (N==1)? (N) : (N*fctrl(N-1)) )

int main()
{
    int m,n=7;
    m = fctrl(n);
    printf("fctrl is %d\n",m);
    return 0;
}

While compiling, I got the following error:

/tmp/ccRODXnZ.o: In function `main':
/home//Desktop/fctrl/fctrl.c:8: undefined reference to `fctrl'
collect2: error: ld returned 1 exit status

Why was this error displayed and how can I fix it?


Solution

  • Macros are not processed by the "actual" C compiler. Macros are processed by c-preprocessor which is merely a text replacement mechanism thus your function-like expression defined as a macro and intended to work as a function does not result with normal function behavior.

    After preprocessing takes place, your program will take the following structure,

    #include <stdio.h>
    
    int main()
    {
        int m,n=7;
        m = ( (n==1)? (n) : (n*fctrl(n-1)) );
        printf("fctrl is %d\n",m);
        return 0;
    }
    

    The question you should ask yourself is where is fctrl function defined? The answer is obvious, it is not defined and that's main reason why you are getting undefined reference to 'fctrl' error.

    Use cpp -nostdinc {filename} or gcc -E -nostdinc {filename} commands on terminal and you will figure out what's going on. By the way, -nostdinc is used to supress inclusion of system header files. cpp is the program to invoke C/C++ preprocessor despite the fact that C/C++ preprocessor can be used for purposes more than mere C/C++ text replacement mechanism. gcc -E option gives the same results with cpp command. In the early days of Unix, preprocessor and compilers used to be separate programs. They are bundled together in today's operating systems.