Undefined reference to `pow' and `floor'
Asked Answered
M

6

144

I'm trying to make a simple fibonacci calculator in C but when compiling gcc tells me that I'm missing the pow and floor functions. What's wrong?

Code:

#include <stdio.h>
#include <math.h>

int fibo(int n);

int main() {
        printf("Fib(4) = %d", fibo(4));
        return 0;
}

int fibo(int n) {
        double phi = 1.61803399;

        return (int)(floor((float)(pow(phi, n) / sqrt(5)) + .5f));
}

Output:

gab@testvm:~/work/c/fibo$ gcc fib.c -o fibo
/tmp/ccNSjm4q.o: In function `fibo':
fib.c:(.text+0x4a): undefined reference to `pow'
fib.c:(.text+0x68): undefined reference to `floor'
collect2: ld returned 1 exit status
Merchantman answered 29/12, 2011 at 17:50 Comment(3)
As the floating point precision isn't infinite, this will give wrong answers for not so large values of nCedrickceevah
Possible duplicate of undefined reference to sqrt (or other mathematical functions)Isaisaac
It seems that an even easier solution exists, simply use g++ instead: g++ fib.c -o fiboBondon
F
279

You need to compile with the link flag -lm, like this:

gcc fib.c -lm -o fibo

This will tell gcc to link your code against the math lib. Just be sure to put the flag after the objects you want to link.

Fugleman answered 29/12, 2011 at 17:52 Comment(10)
Could you please explain how to work out the letter to put after -l?Merchantman
Look in /lib or /usr/lib. The libraries are all named lib<name>.a or lib<name>.so - it's the "<name>" you put after the -l. In this case, the math library is named libm.so, so we call it -lm.Studnia
Thanks! I've been googling for the past 30 minutes and this is the first reference that said to link the libraries after the objectsChic
You can also use LD_PRELOAD to tell ld runtime linker to include libm.so in the memory map and symbol table of the process, so these symbols get loaded and everything works as expectedBygone
Thanks for the answer. But can anybody tell me why in case of codes with a few lines it's okay even if I do not include -lm while compiling ?Supertax
Is this compliant behavior?Michaelemichaelina
Compliant with what? Have to say that the answer is around 9 years old, so it might be outdated :DFugleman
What about just adding #include <cmath>?Blend
In response to @GabrieleCirulli's comment (from ages ago; sorry to @ you now!), I'd like to add that another way to find this out is to look at the man page for the function in question, and in particular the man page in section 3 of the manual -- i.e. type man 3 floor and/or man 3 pow, and they should each make mention of the -lm linker flag.Lentha
@KenIngram: that looks like a C++ version of the header... valid for C++, but a non-C++ C compiler will probably choke on it (gcc does, for me, though g++ is just fine with it.)Lentha
J
27

Add -lm to your link options, since pow() and floor() are part of the math library:

gcc fib.c -o fibo -lm
Jael answered 29/12, 2011 at 17:52 Comment(0)
P
10

For the benefit of anyone reading this later, you need to link against it as Fred said:

gcc fib.c -lm -o fibo

One good way to find out what library you need to link is by checking the man page if one exists. For example, man pow and man floor will both tell you:

Link with -lm.

An explanation for linking math library in C programming - Linking in C

Panslavism answered 15/5, 2015 at 11:36 Comment(0)
A
9

In regards to the answer provided by Fuzzy:

I actually had to do something slightly different.

Project -> Properties -> C/C++ Build -> Settings -> GCC C Linker -> Libraries

Click the little green add icon, type m and hit ok. Everything in this window automatically has -l applied to it since it is a library.

Armhole answered 23/6, 2014 at 11:0 Comment(0)
T
7

To find the point where to add the -lm in Eclipse-IDE is really horrible, so it took me some time.

If someone else also uses Edlipse, here's the way how to add the command:

Project -> Properties -> C/C++ Build -> Settings -> GCC C Linker -> Miscelleaneous -> Linker flags: in this field add the command -lm

Tasso answered 16/10, 2013 at 10:15 Comment(0)
I
4

All answers above are incomplete, the problem here lies in linker ld rather than compiler collect2: ld returned 1 exit status. When you are compiling your fib.c to object:

$ gcc -c fib.c
$ nm fib.o
0000000000000028 T fibo
                 U floor
                 U _GLOBAL_OFFSET_TABLE_
0000000000000000 T main
                 U pow
                 U printf

Where nm lists symbols from object file. You can see that this was compiled without an error, but pow, floor, and printf functions have undefined references, now if I will try to link this to executable:

$ gcc fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

Im getting similar output you get. To solve that, I need to tell linker where to look for references to pow, and floor, for this purpose I will use linker -l flag with m which comes from libm.so library.

$ gcc fib.o -lm
$ nm a.out
0000000000201010 B __bss_start
0000000000201010 b completed.7697
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000000620 t deregister_tm_clones
00000000000006b0 t __do_global_dtors_aux
0000000000200da0 t 
__do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200da8 d _DYNAMIC
0000000000201010 D _edata
0000000000201018 B _end
0000000000000722 T fibo
0000000000000804 T _fini
                 U floor@@GLIBC_2.2.5
00000000000006f0 t frame_dummy
0000000000200d98 t __frame_dummy_init_array_entry
00000000000009a4 r __FRAME_END__
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
000000000000083c r __GNU_EH_FRAME_HDR
0000000000000588 T _init
0000000000200da0 t __init_array_end
0000000000200d98 t __init_array_start
0000000000000810 R _IO_stdin_used
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000000800 T __libc_csu_fini
0000000000000790 T __libc_csu_init
                 U __libc_start_main@@GLIBC_2.2.5
00000000000006fa T main
                 U pow@@GLIBC_2.2.5
                 U printf@@GLIBC_2.2.5
0000000000000660 t register_tm_clones
00000000000005f0 T _start
0000000000201010 D __TMC_END__

You can now see, functions pow, floor are linked to GLIBC_2.2.5.

Parameters order is important too, unless your system is configured to use shared librares by default, my system is not, so when I issue:

$ gcc -lm fib.o
fib.o: In function `fibo':
fib.c:(.text+0x57): undefined reference to `pow'
fib.c:(.text+0x84): undefined reference to `floor'
collect2: error: ld returned 1 exit status

Note -lm flag before object file. So in conclusion, add -lm flag after all other flags, and parameters, to be sure.

India answered 13/9, 2019 at 11:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.