ceil() only works for rvalues [duplicate] - c

This question already has answers here:
Why does the order of '-l' option in gcc matter? [duplicate]
(3 answers)
Closed 3 years ago.
I'm trying to compile this program in ubuntu 18.04, 64 bits:
#include <math.h>
#include <stdio.h>
int main() {
double x = 1.9;
float y = 1.8;
int x2 = ceil(x);
int y2 = ceil(y);
printf("%d, %d\n", x2, y2);
return 0;
}
The gcc command I'm using is:
gcc -std=c99 -lm main.c -o main
And the error I'm obtaining is:
/tmp/ccWL94J9.o: In function `main':
main.c:(.text+0x30): undefined reference to `ceil'
main.c:(.text+0x41): undefined reference to `ceil'
collect2: error: ld returned 1 exit status
Although, if I replace ceil(x) by ceil(1.2) for example, and something similar for ceil(y), I can build and execute the program.
In addition, I have checked that I do have libm.so installed:
bash> find /usr/lib -name "*libm.so*"
/usr/lib/x86_64-linux-gnu/libm.so
What I'm missing?

With the following line, it compiles:
gcc -std=c99 main.c -o main -lm
(putting -lm after -o main)
See https://stackoverflow.com/a/11894098/4030665

With some expressions E, particularly constants, the compiler can evaluate ceil(E) while it is compiling, and it does so if this optimization is not disabled. Then the compiler generates code that uses the result and does not call ceil. When the compiler fails to evaluate ceil(E) during compilation, it generates code that calls ceil.
The switch -lm is an abbreviation for the standard math library. The linker processes input files in the order they appear on the command line. When the linker processes a library, it extracts from the library all object modules that contain a definition for a symbol that is currently needed (referenced but not defined) in the executable file (or other output) it is building.
GCC maintains the order of the various units on its command line. Given -lm main.c, it compiles main.c to product an object module, and then it passes -lm and the object module to the linker in that order. Since the math library is first, when the linker processes it, it has not yet seen any symbols that reference it, and therefore it does not take any modules from the library.
If GCC is instead given main.c -lm, the linker processes the math library after the object module for main. Then, when the linker is processing the math library, it will know that main references ceil, so it will extract from the math library the module that defines ceil.
Thus gcc -std=c99 -lm main.c -o main will work with source code that uses only constants with ceil but will not work with the source code in the example, but gcc -std=c99 main.c -lm -o main will work.

Related

Error "undefined reference to symbol 'sqrt##GLIBC_2.17'" [duplicate]

I have this simple code:
max = (int) sqrt (number);
and in the header I have:
#include <math.h>
But application still says undefined reference to sqrt. Do you see any problem here? It looks like everything should be okay.
You may find that you have to link with the math libraries on whatever system you're using, something like:
gcc -o myprog myprog.c -L/path/to/libs -lm
^^^ - this bit here.
Including headers lets a compiler know about function declarations but it does not necessarily automatically link to the code required to perform that function.
Failing that, you'll need to show us your code, your compile command and the platform you're running on (operating system, compiler, etc).
The following code compiles and links fine:
#include <math.h>
int main (void) {
int max = sqrt (9);
return 0;
}
Just be aware that some compilation systems depend on the order in which libraries are given on the command line. By that, I mean they may process the libraries in sequence and only use them to satisfy unresolved symbols at that point in the sequence.
So, for example, given the commands:
gcc -o plugh plugh.o -lxyzzy
gcc -o plugh -lxyzzy plugh.o
and plugh.o requires something from the xyzzy library, the second may not work as you expect. At the point where you list the library, there are no unresolved symbols to satisfy.
And when the unresolved symbols from plugh.o do appear, it's too late.
I suppose you have imported math.h with #include <math.h>
So the only other reason I can see is a missing linking information. You must link your code with the -lm option.
If you're simply trying to compile one file with gcc, just add -lm to your command line, otherwise, give some informations about your building process.
Just adding the #include <math.h> in c source file and -lm in Makefile at the end will work for me.
gcc -pthread -o p3 p3.c -lm
Here are my observation, firstly you need to include the header math.h as sqrt() function declared in math.h header file. For e.g
#include <math.h>
secondly, if you read manual page of sqrt you will notice this line Link with -lm.
#include <math.h> /* header file you need to include */
double sqrt(double x); /* prototype of sqrt() function */
Link with -lm. /* Library linking instruction */
But application still says undefined reference to sqrt. Do you see any
problem here?
Compiler error is correct as you haven't linked your program with library lm & linker is unable to find reference of sqrt(), you need to link it explicitly. For e.g
gcc -Wall -Wextra -Werror -pedantic test.c -lm
I had the same issue, but I simply solved it by adding -lm after the command that runs my code.
Example.
gcc code.c -lm

Bash script error "undefined reference to sin" [duplicate]

I have this simple code:
max = (int) sqrt (number);
and in the header I have:
#include <math.h>
But application still says undefined reference to sqrt. Do you see any problem here? It looks like everything should be okay.
You may find that you have to link with the math libraries on whatever system you're using, something like:
gcc -o myprog myprog.c -L/path/to/libs -lm
^^^ - this bit here.
Including headers lets a compiler know about function declarations but it does not necessarily automatically link to the code required to perform that function.
Failing that, you'll need to show us your code, your compile command and the platform you're running on (operating system, compiler, etc).
The following code compiles and links fine:
#include <math.h>
int main (void) {
int max = sqrt (9);
return 0;
}
Just be aware that some compilation systems depend on the order in which libraries are given on the command line. By that, I mean they may process the libraries in sequence and only use them to satisfy unresolved symbols at that point in the sequence.
So, for example, given the commands:
gcc -o plugh plugh.o -lxyzzy
gcc -o plugh -lxyzzy plugh.o
and plugh.o requires something from the xyzzy library, the second may not work as you expect. At the point where you list the library, there are no unresolved symbols to satisfy.
And when the unresolved symbols from plugh.o do appear, it's too late.
I suppose you have imported math.h with #include <math.h>
So the only other reason I can see is a missing linking information. You must link your code with the -lm option.
If you're simply trying to compile one file with gcc, just add -lm to your command line, otherwise, give some informations about your building process.
Just adding the #include <math.h> in c source file and -lm in Makefile at the end will work for me.
gcc -pthread -o p3 p3.c -lm
Here are my observation, firstly you need to include the header math.h as sqrt() function declared in math.h header file. For e.g
#include <math.h>
secondly, if you read manual page of sqrt you will notice this line Link with -lm.
#include <math.h> /* header file you need to include */
double sqrt(double x); /* prototype of sqrt() function */
Link with -lm. /* Library linking instruction */
But application still says undefined reference to sqrt. Do you see any
problem here?
Compiler error is correct as you haven't linked your program with library lm & linker is unable to find reference of sqrt(), you need to link it explicitly. For e.g
gcc -Wall -Wextra -Werror -pedantic test.c -lm
I had the same issue, but I simply solved it by adding -lm after the command that runs my code.
Example.
gcc code.c -lm

C libm.a not needed to be linked when compiling

I was trying to compile a source file that includes <math.h>.
However I succeeded in creating an executable, no error without linking to libm.a.
The command I typed was gcc -Wall filename.c -o executablename
I was told to link to the external libraries (i.e/ libraries other than libc.a)
What's going on?
#include <math.h>
#include <stdio.h>
int main(void)
{
double x = sqrt(2.0);
printf ("The sqrt of 2 is: %f\n", x);
return 0;
}
The math functions you call are implemented by compiler built-in functions. Try the following if you want to see an error message:
gcc -fno-builtin -Wall filename.c -o executablename
For example, on my platform (Ubuntu 14.04.3 LTS), I get this error message:
$ cat x.c
#include <math.h>
#include <stdio.h>
int main(void)
{
double x = sqrt(2.0);
printf ("The sqrt of 2 is: %f\n", x);
return 0;
}
$ gcc -fno-builtin x.c
/tmp/ccpjG2Pb.o: In function `main':
x.c:(.text+0x1c): undefined reference to `sqrt'
collect2: error: ld returned 1 exit status
Some compilers, like the current clang on OS X (which masquerades as gcc) do not need to be told to link your executable with the math library.
The clang on OS X will link your executable with /usr/lib/libSystem.B.dylib (and only this for a simple program). This library in turn uses the library /usr/lib/system/libsystem_m.dylib which is the math library.
The functions in <math.h> (or the preferable <tgmath.h>) are part of the C library just as many other functions. It is platform dependent if all the functions in the C library are actually linked in one single library or separately in multiple chunks.
In ancient times the size of the libraries was a problem for link time, the larger a library was, the longer it took to link executables that had many unresolved symbols. These times are long gone, but the separation on some platforms into libc.a and libm.a prevails.
If your platform doesn't need -lm for linking it should have a dummy (empty) version of libm.a just that there is no error when you have that on your link command line. This is for example the case for the musl C library that is at the base of Alpine Linux.

Undefined reference to sqrt (or other mathematical functions)

I have this simple code:
max = (int) sqrt (number);
and in the header I have:
#include <math.h>
But application still says undefined reference to sqrt. Do you see any problem here? It looks like everything should be okay.
You may find that you have to link with the math libraries on whatever system you're using, something like:
gcc -o myprog myprog.c -L/path/to/libs -lm
^^^ - this bit here.
Including headers lets a compiler know about function declarations but it does not necessarily automatically link to the code required to perform that function.
Failing that, you'll need to show us your code, your compile command and the platform you're running on (operating system, compiler, etc).
The following code compiles and links fine:
#include <math.h>
int main (void) {
int max = sqrt (9);
return 0;
}
Just be aware that some compilation systems depend on the order in which libraries are given on the command line. By that, I mean they may process the libraries in sequence and only use them to satisfy unresolved symbols at that point in the sequence.
So, for example, given the commands:
gcc -o plugh plugh.o -lxyzzy
gcc -o plugh -lxyzzy plugh.o
and plugh.o requires something from the xyzzy library, the second may not work as you expect. At the point where you list the library, there are no unresolved symbols to satisfy.
And when the unresolved symbols from plugh.o do appear, it's too late.
I suppose you have imported math.h with #include <math.h>
So the only other reason I can see is a missing linking information. You must link your code with the -lm option.
If you're simply trying to compile one file with gcc, just add -lm to your command line, otherwise, give some informations about your building process.
Just adding the #include <math.h> in c source file and -lm in Makefile at the end will work for me.
gcc -pthread -o p3 p3.c -lm
Here are my observation, firstly you need to include the header math.h as sqrt() function declared in math.h header file. For e.g
#include <math.h>
secondly, if you read manual page of sqrt you will notice this line Link with -lm.
#include <math.h> /* header file you need to include */
double sqrt(double x); /* prototype of sqrt() function */
Link with -lm. /* Library linking instruction */
But application still says undefined reference to sqrt. Do you see any
problem here?
Compiler error is correct as you haven't linked your program with library lm & linker is unable to find reference of sqrt(), you need to link it explicitly. For e.g
gcc -Wall -Wextra -Werror -pedantic test.c -lm
I had the same issue, but I simply solved it by adding -lm after the command that runs my code.
Example.
gcc code.c -lm

sqrt() function not working with variable arguments [duplicate]

This question already has answers here:
sqrt from math.h causes linker error "undefined reference to sqrt" only when the argument is not a constant
(1 answer)
Why am I getting "undefined reference to sqrt" error even though I include math.h header? [duplicate]
(5 answers)
Closed 4 years ago.
I don't know if I'm missing something obvious, but it appears that I'm unable to compute square roots of a variable in C; the sqrt() function only seems to work on constants. This is my code:
#include <math.h>
#include <stdio.h>
int main()
{
double a = 2.0;
double b = sqrt(a);
printf("%f", b);
return 0;
}
When I run this program, I get the following error:
gcc -Wall -o "test2" "test2.c" (in directory: /home/eddy/Code/euler)
/tmp/ccVfxkNh.o: In function `main':
test2.c:(.text+0x30): undefined reference to `sqrt'
collect2: ld returned 1 exit status
Compilation failed.
However, if I replace the argument in sqrt() with a constant such as 2.0 for example, (b = sqrt(2.0)), then it works fine. Is sqrt() not supposed to work with variables or something?
Thanks for the help
You need to link with the math library (use a '-lm' on the command line). In the constant case, the compiler is probably being smart and precomputing sqrt(2.0) (so the code that is compiled is essentially 'b = 1.414...;')
In case of gcc you need to link the library.
gcc filename.c -lm .
However in case of g++ no need to link the library so this will work fine :
g++ filename.c -o filename
Once compilation is successful.
To run simply enter ./filename in G++.
and enter ./a.out in Gcc.
Use the command gcc -Wall -o "test2" "test2.c" -lm which will likely fix this.
This includes the math library in addition to the standard C runtime library. On most systems, the math library is historically a separate entity that needs to be explicitly requested.
Compile with:
gcc -Wall -o test2 test2.c -lm
You need to link against the math library.
include math library using " " operator
#include " math.h "
compile program using -lm option for inherit math library
suppose our program name is test.c the we compile as follow
gcc test.c -lm
gcc does not link the standard libraries by default. So you just need to do this if compiling via gcc:
gcc filename.c -lm .
However in case of g++ no need to link the library so this will work fine :
g++ filename.c -o filename
This works fine for me. I think there is some problem with ur math library. Try linking it again and see. Other wise code is completely perfect.

Resources