Thread: Weird compile errors (gcc, pthread, math)

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    20

    Weird compile errors (gcc, pthread, math)

    Hi. I'm having compile errors with the following code which I cannot debug:

    Code:
    #include <pthread.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define NTHREADS 32
    
    void *Hello(void *threadid){
    	int i;
    	double result = 0.0;
    	sleep(3);
    	
    	for(i = 0; i < 1000; i++){
    		double di = (double) i;
    		result += sin(di) * tan(di);
    	}
    	
    	printf("From thread %d:, Hello world!\n", (int) threadid);
    	
    	pthread_exit(NULL);
    }
    
    int main(){
    	pthread_t threads[NTHREADS];
    	int rc;
    	int t;
    	
    	for(t = 0; t < NTHREADS; t++){
    		rc = pthread_create(&threads[t], NULL, Hello, (void *) t);
    		
    		if(rc){
    			printf("OMG BEARZZZZ with return code %d\n", rc);
    			exit(-1);
    		}
    	}
    	
    	pthread_exit(NULL);
    }
    The errors:

    Code:
    /tmp/ccaU3MYJ.o: In function `Hello':
    threads-math.c:(.text+0x2d): undefined reference to `sin'
    threads-math.c:(.text+0x3b): undefined reference to `tan'
    /tmp/ccaU3MYJ.o: In function `main':
    threads-math.c:(.text+0xc3): undefined reference to `pthread_create'
    collect2: ld returned 1 exit status
    I even try compiling with the following options but still to no avail:

    Code:
    gcc -L /usr/include/pthread.h /usr/include/math.h -o threads-math threads-math.c
    I am particularly frustrated by math.h . The following code compiles well:

    Code:
    #include <stdio.h>
    #include <math.h>
    
    main(){
    	double test = sin(42.0);
    	printf("sin(42) = %f\n", test);
    }
    I am compiling under Ubuntu 9.10 with gcc version: gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1. Any ideas why the "undefined reference"s?

  2. #2
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    You need to link in the math library with -lm.

    Why don't you need to in your second example? Because gcc has built-in support for some math functions, and can decide to use its built-in math functions when it thinks it's appropriate. If you build your larger program with optimization (-O2 for example), that might get gcc to use the built-in versions of sin() and tan(); but even so, you should still use -lm to link in the math library.

    It's kind of silly that some standard functions are not part of libc, but it's done for historical reasons: years ago linkers were not as smart as they are today and by not linking in the math library you avoided bloating your program. Not so with today's libraries (though I suppose there still may exist systems with unintelligent linkers).

    It's also a bad idea to cast an int to a void* when passing it to pthread_create(). There's no guarantee that such a conversion will work. In your case, you can pass the address of your int and things will be fine (assuming you modify Hello() appropriately). Also, you should include unistd.h for sleep().

  3. #3
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    Also, trigonometric functions from math.h such as sin(), cos() and tan() all take their argument expressed in radians. You may know this already but it's hard to tell from your code.

    To convert from degrees to radians you multiply by pi/180.

  4. #4
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    You need to link with pthread also. Your tutorial should tell you how to link ...
    Pay attention!

    > In your case, you can pass the address of your int and things will be fine (assuming you modify Hello() appropriately).


    This example performs argument passing incorrectly. It passes the address of variable t, which is shared memory space and visible to all threads. As the loop iterates, the value of this memory location changes, possibly before the created threads can access it.
    Code:
    for(t=0; t<NUM_THREADS; t++) 
    {
       printf("Creating thread %ld\n", t);
       rc = pthread_create(&threads[t], NULL, PrintHello, (void *) &t);

    https://computing.llnl.gov/tutorials/pthreads/
    Last edited by Bayint Naung; 07-19-2010 at 08:24 AM.

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    20
    Replies...

    You need to link in the math library with -lm.
    That solves my problems with math.h. Thank you.

    Also, trigonometric functions from math.h such as sin(), cos() and tan() all take their argument expressed in radians. You may know this already but it's hard to tell from your code.
    I didn't know this but my main agenda is pthreads so it doesn't matter. Thank you for the info though.

    It's also a bad idea to cast an int to a void* when passing it to pthread_create(). There's no guarantee that such a conversion will work.
    Err...not really my code. I'm just following a threads tutorial I got from school. So, while I'm at it...

    1) Can anyone give me a link to a nice pthreads tutorial? The one I'm currently working on just gives me a bunch of codes without explaining anything (like why it casted a void* to int).

    2) I'm still having compile errors with pthread. My compile call is

    Code:
    gcc -L /usr/include/pthread.h -lm -o threads-math threads-math.c
    And I get the following error:

    Code:
    /tmp/ccIxQjDy.o: In function `main':
    threads-math.c:(.text+0xc3): undefined reference to `pthread_create'
    collect2: ld returned 1 exit status
    Any thoughts?

  6. #6
    Registered User
    Join Date
    Nov 2009
    Posts
    20
    Ooops. While I typed my lengthy update, Bayint posted a reply, which might've answered my new issues. Working on it now till I get new questions. Thanks Bayint!

  7. #7
    Registered User
    Join Date
    Sep 2007
    Posts
    1,012
    This example performs argument passing incorrectly. It passes the address of variable t, which is shared memory space and visible to all threads. As the loop iterates, the value of this memory location changes, possibly before the created threads can access it.
    Nice catch. I didn't look at how the variable was actually being used; big mistake!

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Code in post #1 is also incorrect in that the created threads are not joined or detached.

    You should call pthread_join() or pthread_detach() on all threads that are created join-able.

    See Rationale section here: http://www.opengroup.org/onlinepubs/...ead_join.html#

    You'll have a resource leak otherwise.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. gcc compile problem
    By keyz in forum Linux Programming
    Replies: 3
    Last Post: 05-22-2003, 07:14 AM
  2. Please help with compile for gcc
    By nevermind in forum C++ Programming
    Replies: 2
    Last Post: 10-10-2002, 07:57 PM
  3. GCC compile error coz of file pointer
    By Shadow in forum C Programming
    Replies: 5
    Last Post: 04-20-2002, 12:50 PM
  4. Compile Errors ...
    By ginoitalo in forum C++ Programming
    Replies: 1
    Last Post: 12-31-2001, 02:22 AM
  5. Replies: 4
    Last Post: 11-14-2001, 10:28 AM

Tags for this Thread