Results 1 to 10 of 12
Hello all!
I'm trying to compile program with sqrt() function from math.h. Sometimes it compiles without -lm option, sometimes not. Here's 2 examples. First compiles fine, second outputs errors:
Code:
...
- 07-08-2008 #1Just Joined!
- Join Date
- Dec 2005
- Posts
- 96
C, gcc, math.h and -lm
Hello all!
I'm trying to compile program with sqrt() function from math.h. Sometimes it compiles without -lm option, sometimes not. Here's 2 examples. First compiles fine, second outputs errors:
$ gcc program1.cCode://program1.c #include<stdio.h> #include<math.h> int main(void) { printf("%.0f\n", sqrt(4)); return 0; }
$ ./a.out
2
Now when I'm trying to compile a little bigger program I get these errors:
$ gcc program2.cCode://program2.c #include <stdio.h> #include <math.h> int main(void) { float a,b,c,x1,x2; printf("Enter a\n"); scanf("%d", &a); printf("Enter b\n"); scanf("%d", &b); printf("Enter c\n"); scanf("%d", &c); if ((b*b-4*a*c) < 0) printf("Error:discrimenant is negative. Solution cannot be found\n"); else printf("x1= %d\n", ((-b+sqrt(b*b-4*a*c))/2*a)) && printf("x2= %d\n", ((-b-sqrt(b*b-4*a*c))/2*a)); return 0; }
/tmp/ccEELoaA.o: In function `main':
program2.c
.text+0xe4): undefined reference to `sqrt'
program2.c
.text+0x13a): undefined reference to `sqrt'
collect2: ld returned 1 exit status
I really can't understand what's going on here...
- 07-08-2008 #2
It's not related to "-lm".
correct :
c++ program2.c
or
g++ program2.c
From GNU GCC Info: info (GNU texinfo) 4.11
File: gcc-4.3.info, Node: Invoking G++, Next: C Dialect Options, Prev: Overall Options, Up: Invoking GCC
3.3 Compiling C++ Programs
C++ source files conventionally use one of the suffixes `.C', `.cc',
`.cpp', `.CPP', `.c++', `.cp', or `.cxx'; C++ header files often use
`.hh', `.hpp', `.H', or (for shared template code) `.tcc'; and
preprocessed C++ files use the suffix `.ii'. GCC recognizes files with
these names and compiles them as C++ programs even if you call the
compiler the same way as for compiling C programs (usually with the
name `gcc').
However, the use of `gcc' does not add the C++ library. `g++' is a
program that calls GCC and treats `.c', `.h' and `.i' files as C++
source files instead of C source files unless `-x' is used, and
automatically specifies linking against the C++ library. This program
is also useful when precompiling a C header file with a `.h' extension
for use in C++ compilations. On many systems, `g++' is also installed
with the name `c++'.
When you compile C++ programs, you may specify many of the same
command-line options that you use for compiling programs in any
language; or command-line options meaningful for C and related
languages; or options that are meaningful only for C++ programs. *Note
Options Controlling C Dialect: C Dialect Options, for explanations of
options for languages related to C. *Note Options Controlling C++
Dialect: C++ Dialect Options, for explanations of options that are
meaningful only for C++ programs
- 07-08-2008 #3Just Joined!
- Join Date
- Dec 2005
- Posts
- 96
Well, it works. But why should I use C++ compiler to compile C program?
And still why does first example work while second doesn't?
- 07-08-2008 #4
I don't know what vigol is posting about (gcc is definitely the right program here, since it's a C program), but you are right that this is very strange behaviour.
One possibility, which I have no evidence for, is that in the first case, you are calling sqrt(4). Well, because you are taking sqrt of a static number (as opposed to a variable), it is conceivable that gcc may optimize this away and just replace it with "2". So when the code gets to the linker, the sqrt() call is no longer there.
As I say, this is just a guess, but it makes some sense to me.DISTRO=Arch
Registered Linux User #388732
- 07-08-2008 #5Just Joined!
- Join Date
- Dec 2005
- Posts
- 96
Yep. That's correct. Even if I comment out line with math.h the program still compiles. As soon as I put variable as actual argument, the program refuses to compile.
g++ can compile my program in both cases with no problems at all, thou...
It's strange that no book (well, at least books that I have seen) addresses the issue with -lm option on linux. I found this solution occasionally on some forums.
- 07-08-2008 #6
Your Question was about C and I solved it by C++ !!
I'd have this problem before, and solved by this way!
Frankly, I didn't try to find the origin problem.
You can trace these site for finding (maybe) a practical/theorical solution.
1. C programming.com - Your Resource for C and C++ Programming
2. GCC, the GNU Compiler Collection - GNU Project - Free Software Foundation (FSF)
2.1. GCC online documentation - GNU Project - Free Software Foundation (FSF)
2.2. GCC Frequently Asked Questions - GNU Project - Free Software Foundation (FSF)
2.3. HomePage - GCC Wiki
2.4. Links and Selected Readings - GNU Project - Free Software Foundation (FSF)
If you find it, inform us too.
- 07-09-2008 #7Linux Guru
- Join Date
- Nov 2007
- Location
- Córdoba (Spain)
- Posts
- 1,513
I am not sure and not inclined to search about the thing, but I think that the issue of the original poster is related to what Cabhan said. I think it's gcc making some early substitution that prevents the need to link.
Indeed, it's something we can check easily:
As you can see, libm is not there. In the contrary, if you do this, then it's there:Code:$ gcc test.c $ ./a.out 2 $ ldd a.out linux-vdso.so.1 => (0x00007fffca1fd000) libc.so.6 => /lib/libc.so.6 (0x00007f38c1b18000) /lib64/ld-linux-x86-64.so.2 (0x00007f38c1e6d000)
If you change sqrt(4) by sqrt(a) and define int a=4 elsewhere, then you need to link against the library, because no substitution can be done (my guess is that it would make the thing much more complex, since there should be lots of checks to ensure that a is a constant).Code:$ gcc test.c -lm $ ldd a.out linux-vdso.so.1 => (0x00007fffe9ffe000) libm.so.6 => /lib/libm.so.6 (0x00007f93e1b23000) libc.so.6 => /lib/libc.so.6 (0x00007f93e17ce000) /lib64/ld-linux-x86-64.so.2 (0x00007f93e1da6000)
Not too much people would have noticed this because:
1.- when you use libm, you usually link against libm by using -lm
2.- no one inserts things like sqrt(4) in a program
Go figure when this has been introduced...
The other thing that vigol is speaking about is completely unrelated, which is the capability of g++ to automatically link whatever is needed. You can check with a simple c++ program:
Code:#include<iostream> #include<math.h> int main(void) { int a; std::cout << sqrt(a); return 0; }On the C case, it compiles without lm only if a constant is specified, otherwise you need -lm. On C++, -lm is assumed when needed, and it compiles linking it without a need for -lm on command line. ldd shows it very clearly.Code:$ g++ test.cpp $ ldd ./a.out linux-vdso.so.1 => (0x00007fff4d7fe000) libstdc++.so.6 => /usr/lib/gcc/x86_64-pc-linux-gnu/4.3.1/libstdc++.so.6 (0x00007fc745205000) libm.so.6 => /lib/libm.so.6 (0x00007fc744f82000) libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x00007fc744d6b000) libc.so.6 => /lib/libc.so.6 (0x00007fc744a16000) /lib64/ld-linux-x86-64.so.2 (0x00007fc745510000)
So, both issues are not related really. And C++ has nothing to do with the problem of the original poster.
To be sure about the substitution thing, the best way would be to either ask on the relevant mailing lists or look for changelogs (which can take quite a bit of time, considering that that might have been around for years without me noticing it).
For the rest, you only need to know that gcc needs -lm (for real life cases where you will rarely use a constant), and g++ does not need it because it will like automatically if needed.
- 07-09-2008 #8Just Joined!
- Join Date
- Dec 2005
- Posts
- 96
THX for the input all! Now I've got clear understanding of what's going on.
That's will make life much easier, if gcc would do the same.you only need to know that gcc needs -lm [...] and g++ does not need it because it will like automatically if needed.
- 07-09-2008 #9Just Joined!
- Join Date
- May 2005
- Posts
- 48
void_false
For better results, on the quadradic equation in C the placeholder for float is %f. (In the scanf and printf)
hth && gl
- 07-10-2008 #10Just Joined!
- Join Date
- Dec 2005
- Posts
- 96



