Thread: undefined reference to defined function

  1. #16
    Registered User
    Join Date
    Oct 2006
    Posts
    3,445
    can you provide the ACTUAL function declaration? can you provide the ACTUAL full error message? it just seems like you're asking for help without providing all of the relevant information. I'm surprised that nobody has said anything before. it's likely an extern "C" sort of thing, but we won't know until you give us more relevant info. also, if you don't have the source, but only the .o of one of the objects, you can maybe use objdump or nm to list the symbols in the .o file. you could then use that list to figure out why you're getting the error.

  2. #17
    Registered User
    Join Date
    May 2011
    Posts
    116
    Quote Originally Posted by Elkvis View Post
    can you provide the ACTUAL function declaration? can you provide the ACTUAL full error message? it just seems like you're asking for help without providing all of the relevant information. I'm surprised that nobody has said anything before. it's likely an extern "C" sort of thing, but we won't know until you give us more relevant info. also, if you don't have the source, but only the .o of one of the objects, you can maybe use objdump or nm to list the symbols in the .o file. you could then use that list to figure out why you're getting the error.
    Actually I just found out what it is.Yes you're absolutely right it's an extern "C" thing.I will explain exactly what's going on.

    I have a A.o file (without the source code) which has been compiled with gcc.This file includes all the functions definitions I get the error message undefined reference to <function>.I get this message for every function of A.o I use anywhere in the code.The A.h contains the functions declarations so every .h,.c,.cpp file includes it as #include "A.h" (I have used #pragma once just in case).

    Now,ALL of my other files(no matter if .c or .cpp) have been compiled with g++.So the linker error occurs due to the fact A.o is compiled with gcc.

    I guess I have to use extern "C" in every file?Or just in header files(since .cpp and .c include them)?
    And if so how exactly should I do that?I've never used it before and I barely know even its syntax..

  3. #18
    Registered User
    Join Date
    May 2011
    Posts
    116
    Quote Originally Posted by ZuK View Post
    Looks like you are mixing c and c++.
    A c compiler uses a different name for the same function then a c++ compiler and that might confuse the linker.

    What you exactly have to do depends on what A.o contains

    Looks like the header "A.h" needs needs to have conditions like

    Code:
    #ifdef __cplusplus
       extern "C" {
    #endif
    
    // the functions defined in a c module
    void a_c_function();  
    
    #ifdef __cplusplus
    }
    #endif
    This is the way to enable c++-code to call c function.

    if A.o contains c++ code then you have to conditionally exclude things like class definitions for the c compiler.


    Kurt
    I just saw your post.
    It's the header I have to change?
    Or every file of my program which includes the header?

  4. #19
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    You have to change every header that both the c and the c++ compiler see.
    Kurt

  5. #20
    Registered User
    Join Date
    May 2011
    Posts
    116
    Quote Originally Posted by ZuK View Post
    You have to change every header that both the c and the c++ compiler see.
    Kurt
    The A.h is the only header which has functions that have been compiled with gcc (c functions) --A.o
    All the others have been compiled with g++ and include the A.h
    So only this has to be changed right?

  6. #21
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I believe both function prototypes (declarations) and function definitions need to have extern "C" around them if you want to use the code in C++. This means add ZuK's macros-plus-code to both the sources and the headers. Try it and see what happens.

    There's a bit of confusion in this thread regarding compiling multiple files etc so I'll try to clear that up. If you have one file, you can obviously just use
    Code:
    $ g++ program.cpp -o program
    This preprocesses your source, compiles it, and links it. You can stop the compiler after each of these steps, and one common procedure is to have one command preprocess and compile, and another link.
    Code:
    $ g++ -c program.cpp  # -o program.o is optional
    $ g++ program.o -o program
    Of course, this works well with multiple source files too; you can compile each file with -c, and combine them all together with a "link" g++ command.
    Code:
    $ g++ -c file1.cpp
    $ g++ -c file2.cpp
    $ g++ file1.o file2.o -o program
    However, you can also combine .cpp and .o files in one command line! g++ doesn't care. It just has to do more work when it sees a .cpp file. Also, there's rarely any need to invoke ld manually (although you can if you want). Just saying
    Code:
    $ g++ file1.o file2.o -o program
    is sufficient to link object files together, and it has the added benefit of noticing C++ source files or assembly files and just dealing with them.

    Finally: you can debug all of this yourself if you have the tools to do so. Specifically, "nm" will list all the symbols in an object file. If the symbol looks just like the function name, it's compiled as a C symbol; if it looks mangled, it's compiled as C++. Really, "mangled" is the technical term. Here's an example.
    Code:
    $ cat code.c 
    int func() { return 42; }
    $ gcc -c code.c
    $ nm code.o
    0000000000000000 T func
    $ cp code.c code.cpp
    $ g++ -c code.cpp
    $ nm code.o
    0000000000000000 T _Z4funcv
    $
    The name of the first symbol is "func", which is clearly not mangled. But "_Z4funcv" is mangled. So you can tell whether C or C++ symbols are being put into the file. extern "C" should put a C symbol into the file (so that you can call it from C); if you're getting undefined references to "_Z4funcv" or whatever then there's no extern "C" in the header file. If you don't have extern "C" in the source file then the symbol will be mangled and you won't be able to call it from C.

    There's a useful utility called c++filt that can unmangle symbols for you if they become unreadable: try "nm file.o | c++filt". If you're curious about this stuff, look up "ldd" too, it's pretty useful.

    Finally, the order you specify files in for the g++ command line should only matter for libraries; you can put individual .o files in any order you want. I'm pretty sure of this. Otherwise just about every Makefile ever written would get random linker errors.
    Last edited by dwks; 05-11-2012 at 04:46 PM.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. undefined reference to (function)
    By django in forum C Programming
    Replies: 6
    Last Post: 09-04-2011, 12:06 PM
  2. Replies: 5
    Last Post: 03-07-2011, 01:01 AM
  3. undefined reference to a function
    By ChoCo in forum C Programming
    Replies: 1
    Last Post: 10-04-2009, 12:08 AM
  4. Undefined reference - however they ARE defined
    By scarecrow in forum C++ Programming
    Replies: 4
    Last Post: 05-04-2008, 05:14 PM
  5. undefined reference to a function
    By rodrigouy in forum C Programming
    Replies: 7
    Last Post: 01-17-2006, 06:47 AM