-4

I am using below function which will be launched as seperate thread using pthread_create() api.

static void * threadFunc(void *arg)
{
    char *s = (char *) arg;
    printf("%s", s);
    return (void *) strlen(s);
}

My question:

If the value of strlen(s) is 8(say), On some architectures, return values are stored in %eax. Does this value 8 be visible to main thread in pthread_join() call that launched the above thread?

overexchange
  • 15,768
  • 30
  • 152
  • 347
  • every program has global/stack/heap segment. I guess return values should be in global segment otherwise pthread_join() would not be able to access it, if return value is from stack area. – overexchange Jun 06 '14 at 12:34
  • Is'nt how functions return values implementation depedend? – alk Jun 06 '14 at 12:37
  • To have `pthread_join()` pull a value, use `pthread_exit()` to return from a (P)thread. – alk Jun 06 '14 at 12:39
  • In general, C function call, as per my knowledge return value is stored in accumulator(AC) registre and caller will read that accumulator. but how strlen() works i dont know – overexchange Jun 06 '14 at 12:40
  • @alk In 'void pthread_exit(void *retval);' retval should also not point to stack area. may be we can concentrate on what is currently happening with '(void *)strelen(s)' as per my 2 questions – overexchange Jun 06 '14 at 12:41
  • I did not say that. And your example wouldn't to this either if you'd passed the argument to `return` to `pthread_exit()` instead. It would pass/return `strlen()`'s `size_t` typed result of `8` camouflaged as a `void*`. Dirty, dirty ... ;-) – alk Jun 06 '14 at 12:42
  • 1
    One question per question please. This is not a message board. – Lightness Races in Orbit Jun 06 '14 at 13:01

1 Answers1

0

1) Nope. strlen returns a size_t value on the stack (or in a register depending on the architecture). strlen won't allocate any memory to hold its result.

2) Casting it's return value to (void *) is a pretty bad idea. All you are doing is taking a size_t value (say 8 in your example) and telling the compiler to pretend it is a pointer to a memory area.

None of this is really pthread specific, just normal C. If you want to use the void * as intended, the idea is that you return a pointer to some data structure you have allocated which then needs to be free by the caller.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void *testFunc( char * );


void *testFunc( char *s ){
  size_t *returnMemory = malloc( sizeof( size_t ) );
  size_t len = strlen(s);
  *returnMemory = len;
  return returnMemory;
}

int main( int argc, char *argv[] ){
  void *valPtr = testFunc( "Test String" );
  size_t *sizePtr = (size_t *)valPtr;

  printf( "%p => %zu\n", valPtr, *sizePtr );
  exit(0);
}
tad
  • 506
  • 3
  • 7
  • even if i return just 'strlen(s)' implementation internally casts to void * otherwise pthread_join() cannot accept the returned value. – overexchange Jun 06 '14 at 13:18
  • Yes. The function is defined to return a void *. The point is, if you are sneaking a non-pointer value into it, you will find yourself broken at some point. The intent is that you return a pointer to a data structure that can then be safely used by the parent thread. Instead of passing a char * in the void *arg, you could pass a structure with space for both. – tad Jun 06 '14 at 13:51
  • here returnMemory is passing its value to valPtr, which is heap address, but if i launch testFunc() on a thread then second arg of pthread_join(t,void**) will store &returnMemory, which is stack area. – overexchange Jun 06 '14 at 15:07
  • You might want to have a look at http://stackoverflow.com/questions/8513894/pthread-join-and-pthread-exit – tad Jun 06 '14 at 15:37