Using sqrtf() in C: "undefined reference to `sqrtf'" - c

I am using Linux, Ubuntu 12.04 (Precise Pangolin), and Geany for coding. The code I am writing in C worked completely fine until I used the sqrtf command to find the square root of a float.
Error: HAC3.c:(.text+0xfd7): undefined reference to `sqrtf' .
The part of code I am using sqrtf() in:
float syn(float *a, float *b, int dimensions)
{
float similarity=0;
float sumup=0;
float sumdown=0;
float as=0;
float bs=0;
int i;
for(i=0; i<dimensions; i++)
{
sumup = sumup + a[i] * b[i];
as = as + a[i] * a[i];
bs = bs + b[i] * b[i];
}
sumdown = sqrtf(as) * sqrtf(bs);
similarity = sumup / sumdown;
return similarity;
}
I included math.h, but this doesn't seem to be the problem.
Is there a way to fix Geany so this won't come up again?

Go to Build -> Set Build Commands then under C commands click on the empty label and it will let you specify a new label (name it Link). Type in it gcc -Wall -o "%e" "%f" -lm - where -lm will tell it to link the math library to your app. Click OK.
Then click on Build and select your newly created label - Link. This should do it for you.

You need to link with -lm to provide the math functions.

In addition to the many fine answers here, the portable form of the command that supports C99 version of <math.h> is specified by POSIX as c99 -l m. That having been said, every important Linux compiler supports -lm.

Related

How do I link the Accelerate Framework to a c program in MacOs?

I just started with c development and I need to compile and link a program which uses the Accelerate Framework from Apple:
Simple example accelerate.c:
#include <stdio.h>
#include <Accelerate/Accelerate.h>
double vectorvector_product(double * a, double * b, int dim){
// This function returns in res the elementwiseproduct between a and b,
// a and b must have the same dimension dim.
return cblas_ddot(dim,a,1,b,1);
}
int main(){
double a[4] = {1.0,2.0,3.0,4.0};
double b[4] = {1.0,2.0,3.0,4.0};
double res = vectorvector_product(a,b,4);
printf("Res: %f",res);
}
I compiled it with clang:
>>> cc -Wall -g -c accelerate.c
And obtained a new file accelerate.o
What would I do now in order to properly link it?
All I know is that this Accelerate framework is located at /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework
>>> ls /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/System/Library/Frameworks/Accelerate.framework
Accelerate.tbd Frameworks Headers Modules Versions
p.s.: If I Run this program with Xcode it magically works, but I need to do it from the command line and I would like to know what I'm doing.
Apparently the correct way to link Accelerate.h is by passing -framework Accelerate as argument e.g.
>>> cc -framework Accelerate accelerate.c
will compile and link accelerate.c by generating an executable a.out.

Why does this SIMD example code in C compile with minGW but the executable doesn't run on my windows machine?

I'm learning the basics of SIMD so I was given a simple code snippet to see the principle at work with SSE and SSE2.
I recently installed minGW to compile C code in windows with gcc instead of using the visual studio compiler.
The objective of the example is to add two floats and then multiply by a third one.
The headers included are the following (which I guess are used to be able to use the SSE intrinsics):
#include <time.h>
#include <stdio.h>
#include <xmmintrin.h>
#include <pmmintrin.h>
#include <time.h>
#include <sys/time.h> // for timing
Then I have a function to check what time it is, to compare time between calculations:
double now(){
struct timeval t; double f_t;
gettimeofday(&t, NULL);
f_t = t.tv_usec; f_t = f_t/1000000.0; f_t +=t.tv_sec;
return f_t;
}
The function to do the calculation in the "scalar" sense is the following:
void run_scalar(){
unsigned int i;
for( i = 0; i < N; i++ ){
rs[i] = (a[i]+b[i])*c[i];
}
}
Here is the code for the sse2 function:
void run_sse2(){
unsigned int i;
__m128 *mm_a = (__m128 *)a;
__m128 *mm_b = (__m128 *)b;
__m128 *mm_c = (__m128 *)c;
__m128 *mm_r = (__m128 *)rv;
for( i = 0; i <N/4; i++)
mm_r[i] = _mm_mul_ps(_mm_add_ps(mm_a[i],mm_b[i]),mm_c[i]);
}
The vectors are defined the following way (N is the size of the vectors and it is defined elsewhere) and a function init() is called to initialize them:
float a[N] __attribute__((aligned(16)));
float b[N] __attribute__((aligned(16)));
float c[N] __attribute__((aligned(16)));
float rs[N] __attribute__((aligned(16)));
float rv[N] __attribute__((aligned(16)));
void init(){
unsigned int i;
for( i = 0; i < N; i++ ){
a[i] = (float)rand () / RAND_MAX / N;
b[i] = (float)rand () / RAND_MAX / N;
c[i] = (float)rand () / RAND_MAX / N;
}
}
Finally here is the main that calls the functions and prints the results and computing time.
int main(){
double t;
init();
t = now();
run_scalar();
t = now()-t;
printf("S = %10.9f Temps du code scalaire : %f seconde(s)\n",1e5*sum(rs),t);
t = now();
run_sse2();
t = now()-t;
printf("S = %10.9f Temps du code vectoriel 2: %f seconde(s)\n",1e5*sum(rv),t);
}
For sum reason if I compile this code with a command line of "gcc -o vec vectorial.c -msse -msse2 -msse3" or "mingw32-gcc -o vec vectorial.c -msse -msse2 -msse3"" it compiles without any problems, but for some reason I can't run it in my windows machine, in the command prompt I get an "access denied" and a big message appears on the screen saying "This app can't run on your PC, to find a version for your PC, check with the software publisher".
I don't really understand what is going on, neither do I have much experience with MinGW or C (just an introductory course to C++ done on Linux machines). I've tried playing around with different headers because I thought maybe I was targeting a different processor than the one on my PC but couldn't solve the issue. Most of the info I found was confusing.
Can someone help me understand what is going on? Is it a problem in the minGW configuration that is compiling in targeting a Linux platform? Is it something in the code that doesn't have the equivalent in windows?
I'm trying to run it on a 64 bit Windows 8.1 pc
Edit: Tried the configuration suggested in the site linked below. The output remains the same.
If I try to run through MSYS I get a "Bad File number"
If I try to run throught the command prompt I get Access is Denied.
I'm guessing there's some sort of bug arising from permissions. Tried turning off the antivirus and User Account control but still no luck.
Any ideas?
There is nothing wrong with your code, besides, you did not provide the definition of sum() or N which is, however, not a problem. The switches -msse -msse2 appear to be not required.
I was able to compile and run your code on Linux (Ubuntu x86_64, compiled with gcc 4.8.2 and 4.6.3, on Atom D2700 and AMD Athlon LE-1640) and Windows7/64 (compiled with gcc 4.5.3 (32bit) and 4.8.2 (64bit), on Core i3-4330 and Core i7-4960X). It was running without problem.
Are you sure your CPU supports the required instructions? What exactly was the error code you got? Which MinGW configuration did you use? Out of curiosity, I used the one available at http://win-builds.org/download.html which was very straight-forward.
However, using the optimization flag -O3 created the best result -- with the scalar loop! Also useful are -m64 -mtune=native -s.

Compile error using sqrt() in c

I have a problem using sqrt() in c.
I'm trying to do something like this:
int a;
a = sqrt(9);
etc
I'm restricted to use:
gcc -ansi -Wall -pedantic oneFile.c anotherFile.c thirdFile.c -o outputFileName
How can I make this compile without using the -lm command?
Yes, I have #include !
Is there any way around this and still use sqrt()?
Thanks
You can't make it compile without -lm. That's an instruction to the linker to compile against the built-in math library. It isn't enough to say #include <math.h>, because that's only a header file - there's no code in there, that simply tells the compiler what the functions you're using look like. You still need to actually get the implementation of that function into your code, and -lm basically tells the linker look in libm, check to see if it has any functions that we haven't found yet. If you don't look in there, you'll never be able to actually execute sqrt because the code simply isn't in your program.
If you're working on a homework assignment and are restricted to using that command line, then it's possible that part of your assignment is to not use anything from the math library, and so you may be expected to consider an alternate approach.
just try with this function, If you don`t want to use library.
Sq_root(n)
{
count=0;
int i = 0;
for(i=1;sum<=n;i+=2)
{
sum+=i;
count++;
}
return (count);
}
This will work, without any math library.
use #include <math.h> in header
else use user define function
int int_sqrt(int x){
int s, t;
s = 1; t = x;
while (s < t) {
s <<= 1;
t >>= 1;
}
do {
t = s;
s = (x / s + s) >> 1;
} while (s < t);
return t;
}

gcc 4.2.1 Linking issue: Undefined Symbols for Architecture x86_64

Yes, it's been asked before, but every answer I come up with on SO and elsewhere has to do with compiling C++ code in gcc instead of g++, or a issue of some kind with standard libraries. So far, nothing actually lining up right for me here.
So, I'm going through a basic crash course on C, and trying to compile an example used to illustrate linking to files that you create, rather than from the standard libraries. Here's the code:
math_functions.h
int sum (int x, int y);
float average (float x, float y, float z);
math_functions.c
int sum (int x, int y)
{
return (x + y);
}
float average (float x, float y, float z)
{
return (x + y + z) / 3;
}
and finally
test3.c
#include <stdio.h>
#include "math_functions.h"
main ()
{
int theSum = sum (8, 12);
float theAverage = average (16.9, 7.86, 3.4);
printf ("the sum is: %i ", theSum);
printf ("and the average is: %f \n", theAverage);
printf ("average casted to an int is: %i \n", (int)theAverage);
}
These are all in the same folder. When I open the Terminal, cd to the folder and run:
gcc test3.c -o test3
I get:
Undefined symbols for architecture x86_64:
"_average", referenced from:
_main in ccmf69Tt.o
"_sum", referenced from:
_main in ccxms0fF.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
This happens if I use gcc or g++ (which I shouldn't have to do, since this should all be C), and everything I've compiled before now works fine with the
#include <stdio.h>
at the top.
I can get it to compile and run fine by removing the
#include "math_functions.h"
from the test3.c file, putting the contents of math_functions.h before main() and the contents of math_functions.c after main(). And yes, that is copy and paste, so its definitely the same code.
So yeah, I can get my code to work, but it defeats the purpose of the exercise, in that I don't end up being able to use that code in any other C files without copying it and pasting it into the one file...
So I'm wondering, is there a way I can fix this, so I can include more that just the standard C, C++ and Objective-C libraries?
This happens through box the Terminal, manually typing out the gcc command, and through CodeRunner, which has the standard commands all tucked away into a button, so I can't stuff it.
I'm running Mountain Lion 10.8.4 (12E55) on a 2012 Mac Mini, using the Command Line Tools from Xcode 4.6.2 (installed them just a few hours ago, I haven't actually done much then standard use of the Mini till now)
I have all the same software installed on my MacBook Air, but haven't tested it to see if the same goes down yet.
Any pointers? If someone else has had this and worked it out somewhere here on SO, please point me at it, I have been looking for round an hour but like I said before, all the solutions that I've found so far end up being when there is C++ code or something weird with the standard libraries.
You just need to compile the maths_function. The linker is complaining it does not have the definitions contained in that module.
gcc test3.c math_functions.c -o test3

C programming - "Undefined symbol referenced in file"

I am trying to write a program to approximate pi. It basically takes random points between 0.00 and 1.00 and compares them to the bound of a circle, and the ratio of points inside the circle to total points should approach pi (A very quick explanation, the specification goes in depth much more).
However, I am getting the following error when compiling with gcc:
Undefined first referenced
symbol in file
pow /var/tmp//cc6gSbfE.o
ld: fatal: symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status
What is happening with this? I've never seen this error before, and I don't know why it's coming up. Here is my code (though I haven't fully tested it since I can't get past the error):
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void) {
float x, y;
float coordSquared;
float coordRoot;
float ratio;
int n;
int count;
int i;
printf("Enter number of points: ");
scanf("%d", &n);
srand(time(0));
for (i = 0; i < n; i++) {
x = rand();
y = rand();
coordSquared = pow(x, 2) + pow(y, 2);
coordRoot = pow(coordSquared, 0.5);
if ((x < coordRoot) && (y < coordRoot)) {
count++;
}
}
ratio = count / n;
ratio = ratio * 4;
printf("Pi is approximately %f", ratio);
return 0;
}
use -lm during compilation(or linking) to include math library.
Like this: gcc yourFile.c -o yourfile -lm
need to Link with -lm.
gcc test.c -o test -lm
The error is produced by the linker, ld. It is telling you that the symbol pow cannot be found (is undefined in all the object files handled by the linker). The solution is to include the library which includes the implementation of the pow() function, libm (m for math). [1] Add the -lm switch to your compiler command line invocation (after all the source file specifications) to do so, e.g.
gcc -o a.out source.c -lm
[1] Alternatively, you could have your own implementation of pow() in a separate translation unit or a library, but you would still have to tell the compiler/linker where to find it.

Resources