I've been experimenting with openmp and some math functions in C. If I try to declare and initialize some variables outside a parallel construct, then use them within a math function inside the parallel, when I compile using gcc -fopenmp practice.c -o practice I get the following error:
/usr/bin/ld: /tmp/ccQj4iIQ.o: in function `main._omp_fn.0':
practice.c:(.text+0xb3): undefined reference to `fmax'
collect2: error: ld returned 1 exit status
This issue happens with fmax, fmin, sqrt, pow, cos, etc. Some sample code that illustrates this is:
#include <omp.h>
#include <math.h>
void main(void){
double m=1;
double a=12;
#pragma omp parallel
{
m = fmax(m,a);
}
}
I've found that the issue goes away if I 1) move the fmax outside the parallel, or 2) re-initialize the variables inside the parallel, or 3) use fmax on 1 and 12 directly instead of m and a. This issue also does NOT occur if I simply try to use printf to print m and a inside the parallel, so I know each thread can "see" the values correctly.
Why is this happening, and is there a way to fix it other than the 3 things I've already tried? So far it seems like 2) is my best bet, but it seems silly to have to do initialization immediately inside the parallel when it would make more sense to do it beforehand.
Related
Well, I think my problem is a little bit interesting and I want to understand what's happening on my Ubuntu box.
I compiled and linked the following useless piece of code with gcc -lm -o useless useless.c:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * 440 * ((float) 1/44100)));
return(0);
}
So far so good. But when I change to this:
/* File useless.c */
#include <stdio.h>
#include <math.h>
int main()
{
int freq = 440;
int sample = (int)(0.75 * 32768.0 * sin(2 * 3.14 * freq * ((float) 1/44100)));
return(0);
}
And I try to compile using the same command line, and gcc responds:
/tmp/cctM0k56.o: In function `main':
ao_example3.c:(.text+0x29): undefined reference to `sin'
collect2: ld returned 1 exit status
And it stops. What is happening? Why can't I compile that way?
I also tried a sudo ldconfig -v without success.
There are two different things going on here.
For the first example, the compiler doesn't generate a call to sin. It sees that the argument is a constant expression, so it replaces the sin(...) call with the result of the expression, and the math library isn't needed. It will work just as well without the -lm. (But you shouldn't count on that; it's not always obvious when the compiler will perform this kind of optimization and when it won't.)
(If you compile with
gcc -S useless.c
and take a look at useless.s, the generated assembly language listing, you can see that there's no call to sin.)
For the second example, you do need the -lm option -- but it needs to be at the end of the command line, or at least after the file (useless.c) that needs it:
gcc -o useless useless.c -lm
or
gcc useless.c -lm -o useless
The linker processes files in order, keeping track of unresolved symbols for each one (sin, referred to by useless.o), and then resolving them as it sees their definitions. If you put the -lm first, there are no unresolved symbols when it processes the math library; by the time it sees the call to sin in useless.o, it's too late.
I have 3 files in my directory:
ex22.h, ex22.c. ex22_main.c
ex22.h:
#ifndef _ex22_h
#define _ex22_h
extern double* v;
...
#endif
ex22.c:
#include <stdio.h>
#include "ex22.h"
double* v;
/*a function that accepts a new_variable, changes a
static variable inside of it while keeping track of
what the static variable was before the change. The
purpose of the function is to update the static
variable and print what it was right before the
updating.*/
double update_variable(double new_variable)
{
static double variable = 1.0;
double old_variable = variable;
variable = new_variable;
v = &variable;
return old_variable;
}
...
ex22_main.c:
#include "ex22.h"
#include "dbg.h"
...
int main(void)
{
//test if it is possible
printf("Variable at first: %f", update_variable(2.0);
printf("Access 'variable' inside update_variable: %f", *v);
}
Compiller (ubuntu) gives me those error messages:
cc ex22_main.c -o ex22_main
/tmp/ccGLFiXP.o: In function `main':
...
ex22_main.c:(.text+0x1f4): undefined reference to `update_variable'
ex22_main.c:(.text+0x222): undefined reference to `r'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'ex22_main' failed
make: *** [ex22_main] Error 1
Hope you understood what I'm trying to achieve. My goal is to access the static variable inside a function (which is not possible) by making a pointer to it. I'm just curious if it works that way?
EDIT:
There were some stupid bugs in my code but the idea of accessing a static variable inside a function by it's pointer is completely feasible.
Avoid my mistakes:
1) Make sure files are linked
2) Watch out for variable names
My goal is to access the static variable inside a function (which is not possible) by making a pointer to it. I'm just curious if it works that way?
Yes, it does. static has a different meaning for variables declared inside functions than for those declared at file scope, but but both varieties exist and have the same address for the entire lifetime of the program. A pointer to such a variable can be used to access its value anywhere in the program, without regard to whether the variable can be accessed via its declared identifier at the point of access-via-pointer.
Your compilation issue is unrelated. Your other answer explains the nature of that problem.
The compiler, or more precisely the linker, can't find the definitions of update_variable or r because you didn't compile and link ex22.c which contains those definitions.
You need to compile both files and link them together.
cc -o ex22_main ex22_main.c ex22.c
I'm trying to set a function pointer to point to the pow function.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void){
double (*func)(double, double) = pow;
return 0;
}
But the program doesn't compile.
I get this error:
$ gcc test.c -o test
/tmp/ccD6Pmmn.o: In function `main':
test.c:(.text+0x8): undefined reference to `pow'
collect2: error: ld returned 1 exit status
I'm using Ubuntu 15.10.
Anyone knows what's wrong with my code?
Thanks
You need to compile with -lm via command line or configure your IDE to add it into the linking process. This is due to the fact that some libraries are pretty large and to avoid taking up space in your program and compilation time, this was setup at the beginning of C when computers were much slower and would take MUCH more to compile and a matter of space was CRUCIAL.
I'm an absolute beginner to C and I've read a few books but never really played with it. I'm starting to try to apply what I've read with a very simple program that returns the sin of a number. The hardest thing I've encountered with C is knowing how and when to use pointers.
I'm sure this is simple but here is how I've written my test:
#include <stdio.h>
#include <math.h>
int main(void)
{
double x;
printf("Enter a number to calculate the sin(x): \n");
scanf("%lf", &x);
printf("sin(%lf) = %lf\n", x, sin(x));
return 0;
}
I'm compiling and executing this code in Ubuntu
gcc -lm sinCalc.c && ./a.out
Error I'm receiving is this:
/tmp/blaha.o: In function `main':
sinCalc.c:(.text+0x31): undefined reference to `sin'
collect2: ld returned 1 exit status
Undefined symbols are resolved left to right, so
gcc sinCalc.c -lm && ./a.out
should work.
Are they [structs] like an interface in Java?
No. Structs are an aggregate of a number (1 or more) of types that can be dealt with as a single unit in certain circumstances (assignment, parameter passing).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
undefined reference to pthread_create in linux (c programming)
I am trying to implement Thread chain in Ubuntu in C. When I compile the following code, I get the errors of Undefined reference to these thread library function even though I have added the header file.I am also getting segmentation fault error. Why is that? I am not accessing some uninitialized memory anywhere in program. Here is the code:
#include <stdio.h>
#include<stdlib.h>
#include <pthread.h>
void* CreateChain(int*);
int main()
{
int num;
pthread_t tid;
scanf("Enter the number of threads to create\n %d",&num);
pthread_create(&tid,NULL,CreateChain,&num);
pthread_join(tid,NULL);
printf("Thread No. %d is terminated\n",num);
return 0;
}
void* CreateChain(int* num )
{
pthread_t tid;
if(num>0)
{
pthread(&tid,NULL,CreateChain,num);
pthread_join(tid,NULL);
printf("Thread No. %d is terminated\n",*num);
}
else
return NULL;
return NULL;
}
I am getting following warnings and the Scanf prompt is not appearing for some reason.
Regards
The pthread.h header file provides a forward declaration of pthread functions. This tells the compiler than these functions exist and have a certain signature. It doesn't however tell the linker anything about where to find these functions at runtime.
To allow the linker to resolve these calls (decide where to jump to inside your code or in a different shared object), you need to link against the appropriate (pthread) library by adding
-pthread
to your build command line.
[Note that it is also possible to use -lpthread. This previous question expains why -pthread is preferable.]
There are various other issues with the code that will be worthy of attention
The scanf line should be split into printf("Enter number of threads\n");scanf("%d", &num); to get the user prompt displayed
The signature of CreateChain is wrong - it should take a void* argument instead. You can always do something like int num = *(int*)arg; inside the function to retrieve the number of threads.
The logic inside CreateChain looks wrong. You currently compare a pointer against 0 - I presume you mean to compare the number of threads instead? Also, if you don't decrement the number of threads to create somewhere, you'll end up with code that creates threads forever (or until you run out of handles depending on how the different threads get scheduled).
Try compiling like this below :
gcc -Wall -pthread test.c -o test.out
-pthread is an option to tell linker explicitly to resolve the symbols related to <pthread.h>
add -lpthread
gcc -o test test.c -lpthread