4
votes

I cannot figure out how to fix this linking problem in GCC.
I am running CodeBlocks 13.12, under Windows 8, GCC+MingWG 4.8.1.
I have created a project having two files:

main.c

#include <complex.h>
int main(void)  
{  
    double complex (*FUNC)(double complex) = conj;   
    return 0;  
}  

test.c

#include <complex.h>  
double complex (*CEXP)(double complex) = cexp;  
double complex (*CONJ)(double complex) = conj;  

When the project is compiled in CodeBlocks (I use the compiler option -std=c11, only),
an error results, saying: "Undefined reference to conj".

I think this is extrange, since the function conj is defined in complex.h, as function cexp is, but the reference to cexp seems to work well.

On the other hand, the error is not triggered for the reference to conj in file main.c.
(SORRY: It seems that the error is triggered in main.c, also)

Is this a particular issue of GCC?
How I must configure CodeBlocks to fix this problem?
Thanks in advance.

More information. The compiler window shows these lines in CodeBlocks:

mingw32-gcc.exe -Wall -g -std=c11 -g -std=c11 -c C:\Users\Machine\Desktop\myapp\myapp.c -o obj\Debug\myapp.o
mingw32-gcc.exe -Wall -g -std=c11 -g -std=c11 -c C:\Users\Machine\Desktop\myapp\test.c -o obj\Debug\test.o
mingw32-g++.exe -o bin\Debug\myapp.exe obj\Debug\myapp.o obj\Debug\test.o
obj\Debug\myapp.o: In function main': C:/Users/Machine/Desktop/myapp/myapp.c:9: undefined reference toconj' obj\Debug\test.o:test.c:(.data+0x4): undefined reference to `conj' collect2.exe: error: ld returned 1 exit status

ALSO: I've tried to write the option -lm in several places on CodeBlocks without any success (for example, in Settings/Compiler/Other options, or Settings/Compiler/Linker, or Project/Build options..., etc.).

MOREOVER: The function conj is defined as "inline" by MinGW32 in complex.h. I souspect that this could be the problem, but using option -fno-inline has not any effect.

NM program: By following the suggestion of o11c, I used the nm program. The following output is obtained:

<snip, not what was needed>
2
You may need to explicitly link against the math library (-lm flag). - Ismail Badawi
@IsmailBadawi: And how do I do that in CodeBlocks? I tried to add the -lm option in several places, but it does not work. - pablo1977
I am not sure, but I think that it's a bug of MinGW, related to the inline definitions in complex.h. - pablo1977
Neither inline or extern inline should lead to linker errors. Do you have the nm executable to list symbols in your libm.dll ? - o11c
@o11c: I run nm with parameter -C and obtained the output that is shown in the bottom of my question. I don't know if this is useful or correct. - pablo1977

2 Answers

4
votes

Okay, I think I see where your problem is now; you are trying to take the entry-point addresses of conj() and cexp(), which works for cexp(), but not for conj(). The explanation is that cexp() is a real external function, for which you can obtain an address, but, if you are using a mingwrt-3.x predating mingwrt-3.21, (or any broken, and now withdrawn mingwrt-4.x release), conj() is implemented as __inline__, with no corresponding external implementation, so there is no way to get its address.

I've fixed this issue, in mingwrt-3.21, so you should ensure that you are using that, (preferably the mingwrt-3.21.1 release).

0
votes

I turned my comment on Keith Marshall's answer into an answer as well (as it's too long for a comment):

As per Keith Marshall's answer, the problem is that they are inline, and that gcc is not producing a non-inlined version.

To get around this, add

static double complex conj_ (double complex a)
{
    return conj (a);
}

etc. - you can take the addresses of these, and if ever conj becomes non-inline, the function should optimise out to a simple address of conj.