John Smith
John Smith

Reputation: 45

Passing a struct to a thread

Sorry for the second post, I find threads really complicated.. I am trying to pass a struct to a thread parameter, but I get the error:

 error: dereferencing pointer to incomplete type
 printf("%d\n", assembly->size);

I am not sure how to fix it, here is my main code(test.c).

#include "test.h"


int main()
{

    assembly.size = 10;

    pthread_t thread_tid;
    pthread_create(&thread_tid, NULL, foo, &assembly);

    pthread_join(thread_tid, NULL);

return 0;
}

The function that the thread calls(test1.c):

void * foo(void *param)
    {
        struct factory *assembly = param;
        printf("%d\n", assembly->size);
        return NULL;
    }

My header file which holds the struct definition(test.h):

#ifndef TEST1_H
#define TEST1_H

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "test1.c"

struct factory{
    int size;
    int products_per_box;
    int products_to_assemble;
};
struct factory assembly;

void * foo(void *param);

#endif

Upvotes: 0

Views: 3426

Answers (2)

The reason is that you are #including your other .c file to make them into 1 compilation unit (which is wrong). After preprocessing, the code in the test.c compilation unit will be something like:

/* contents of <stdio.h> */
/* contents of <stdlib.h> */
/* contents of <pthread.h> */

void * foo(void *param)
{
    struct factory *assembly = param;
    printf("%d\n", assembly->size);   // this line needs knowledge...
    return NULL;
}

struct factory{                    
    int size;
    int products_per_box;
    int products_to_assemble;
};                                    // ...that is available only after this 
                                      // line in this compilation unit



struct factory assembly;
void * foo(void *param);

int main()
{

    assembly.size = 10;

    pthread_t thread_tid;
    pthread_create(&thread_tid, NULL, foo, &assembly);

    pthread_join(thread_tid, NULL);

return 0;
}

Notice yet? C compiler works from top to down. At the line printf("%d\n", assembly->size); the compiler does not know of what type the member size is, nor does it know whether the struct factory even has a member so called.

What you need to do is to have test1.c #include "test.h" and compile test1.c separately:

#include "test.h"  

void * foo(void *param)
{
    struct factory *assembly = param;
    printf("%d\n", assembly->size);
    return NULL;
}

Also, you'd want to move the declaration of struct factory assembly out of the header file, into the main.c, or otherwise every single compilation unit that has that header file included would get that variable declared.

And then you can compile and link them together using one command for example by:

% gcc test.c main.c -o program

or by compiling each separately

% gcc -c test.c
% gcc -c main.c
% gcc -o program test.o main.o

Upvotes: 3

Ed Heal
Ed Heal

Reputation: 60037

1) Remove this line from test.h - You do not need it

  struct factory assembly;

2) In main add the line just before assembly.size=10;

   struct factory assembly;

3) Add a cast i.e. change

 struct factory *assembly = param;

to

struct factory *assembly = (struct factory *)param;

4) As others have pointed out - delete this line

#include "test1.c"

In general you only include header files

Upvotes: -1

Related Questions