0

I am just a beginner in C++. I am trying to construct some header file header.h, but the output is always like the following:

/tmp/ccTmZKXX.o: In function `main':
main.c:(.text+0x13): undefined reference to `func'
collect2: ld returned 1 exit status

Could you please help me to see whether my way of using header file is correct or not? Thanks a lot!

Main code (main.c):

#include "stdio.h"
#include "func.h"

main() {
    double a = f(2.3);
    printf("a=%f\n", a);
}

where func.c contains:

double func (double x) { return x ;}

where func.h contains:

double func (double);

And I compile with:

gcc -o main main.c
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
user1159975
  • 103
  • 2

3 Answers3

5

There are multiple problems here:

  1. The C++ compiler in the GCC (GNU Compiler Collection) is g++, not gcc; the latter is the GNU C Compiler.

  2. The code in main.c is a (not very good) C program and not a C++ program. C99 outlawed the implicit int return type; C++ essentially never allowed it.

  3. Your question uses a function f; your compilation error references func. This means you did not show us exactly the code you tried to compile.

  4. The standards say #include <stdio.h>; you should too.

    #include <stdio.h>
    #include "func.h"
    
    int main()
    {
        double a = func(2.3);
        printf("a=%f\n", a);
    }
    

    NB: This is a perfectly good C program if you work with C99. In C89, you are expected to return a value from main() rather than 'fall off the end'. C99 follows C++98 and allows falling off the end as equivalent to an explicit return 0;. I tend to put the explicit return(0); (usually with, sometimes without, the parentheses - the compilers don't mind either way) anyway. (I compile C with -Wstrict-prototypes; to get a warning-free compilation, I write int main(void), which also works with C++ but the void is not necessary there.)

  5. The header is OK, though you will learn in due course about header guards and other paraphernalia that make headers more reliable.

    #ifndef FUNC_H_INCLUDED
    #define FUNC_H_INCLUDED
    
    extern double func(double a);
    
    #endif /* FUNC_H_INCLUDED */
    

    The extern is not mandatory. I tend to use it, but there are many who do not.

  6. The source file defining the function should include the header to ensure that the function definition is consistent with the declaration. All code that uses the function should include the header so that there is a prototype in scope. This cross-checking is crucial for reliability. C++ requires prototypes in scope before a function is used; it does not demand a prototype in scope before the function is defined (but it is good practice to do so). It is strongly recommended in C that you have a prototype in scope before defining an external (non-static) function. You can use -Wmissing-prototypes with C code and GCC to spot such problems, but the option is not valid for G++.

    #include "func.h"
    
    double func(double x) { return x; }
    
  7. Since this is a C++ question, we could consider inlining the function in the header. Indeed, C99 also supports inline functions. However, we can ignore that for the time being.

  8. Since this is a C++ question, we could consider that using <stdio.h> is not good because it is not type safe. You might be better off using <iostream> et al, not least because they are type safe.

    #include <iostream>
    #include "func.h"
    
    int main()
    {
        double a = func(2.3);
        std::cout << "a=" << a << std::endl;
    }
    
  9. The correct compilation requires both the main program and the function it invokes, so you might write:

    g++ -o main main.c func.c
    

    Or, if you are compiling it in C, then:

    gcc -std=c99 -o main main.c func.c
    

    Note that the -std=c99 is necessary to ensure that the absence of return in main() is acceptable.

    Note that there are several extensions in use for C++ source code, including .C, .cpp and .cxx, all of which are accepted by G++ (as well as .c).

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
4

There are several things wrong here.

  1. Define the function as follows in func.h

    extern double func(double);
    
  2. When compiling, provide all source (c, cpp) files

    gcc main.c func.c -o main
    

You should be good to go.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Pavan Yalamanchili
  • 12,021
  • 2
  • 35
  • 55
  • 1
    Erm, why would you need to declare the function `extern`? What does that accomplish? – Cody Gray - on strike Jan 20 '12 at 06:08
  • 1
    The `extern` is optional (I tend to use it) but not mandatory. Otherwise, you are correct. Later, you might choose to compile individual source files to object (`gcc -c`) and then link the object files (`gcc -o program file1.o file2.o ...`), and you might need to specify libraries and perhaps library directories too. – Jonathan Leffler Jan 20 '12 at 06:36
  • I finally use # include in my main.c. It works now. Thanks a lot for all the help! – user1159975 Jan 21 '12 at 07:23
  • @user1159975 dont *ever* include func.c in a your c file. This will break all things if you include it in multple files. Please read what Johnathan leffler said in his comment and follow it to the letter. – Pavan Yalamanchili Jan 21 '12 at 08:31
1

Compile like this:

gcc -o main main.c func.c

Then it will be fine.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Dinesh Reddy
  • 775
  • 1
  • 11
  • 25