definition conflict in pthread.h

NanoGoner (26)
I have had several problems with pthread.h. The latest is a definition conflict.

The code is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/* Main.c for PC side of control fed to
* AVR by UART/ RS232
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>

void *control_updater (unsigned char rs232_control[10][10]);
int main(int argc, char **argv)
{                                                            // <------  This is line 20
    control_init();

    pthread_t control_thread;
    int iret, i, x;

    iret = pthread_create(&control_thread, NULL, control_updater, rs232_control);


    while (1)
    {
        printf("Control: sidewaves\n");                          // sidewaves
        sidewaves(2000,100);

        printf("Control: ripples\n");                            // ripples
        ripples(2000,100);

        printf("Control: spinwave\n");                           // spinwave
        spin(2000,100);

        printf("Control: sinewaves\n");                          // Sinelwave
        sinelines(2000,100);

        printf("Control spherical\n");                         // Spherical
        spherical1500,100);

        printf("Control: Explosive");                          // Explosive
        fireworks(7,50,1200);

     }

}

void *control_updater (unsigned char rs232_control[10][10])
{
    unsigned char send_control[10][10];

    while (1)
    {
        memcpy(send_control, rs232_control, 100);
        control_push(send_control);
    }
}



There are numerous other files.

The compiler error is:
--------------------------------------------------------------------------
/home/bruce/Desktop/main.c|26|warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [enabled by default]|\

/usr/include/pthread.h|225|note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(unsigned char (*)[8])’|

||=== Build finished: 1 errors, 8 warnings ===|
---------------------------------------------------------------------------
The definition in conflict in pthread.h is:
---------------------------------------------------------------------------

/* Create a new thread, starting with execution of START-ROUTINE
getting passed ARG. Creation attributed come from ATTR. The new
handle is stored in *NEWTHREAD. */

extern int pthread_create (pthread_t *__restrict __newthread,
__const pthread_attr_t *__restrict __attr,
void *(*__start_routine) (void *),// <--problem rea
void *__restrict __arg) __THROWNL __nonnull ((1, 3));

--------------------------------------------------------------------------------

It seems to say that the arguement " void*(*_start_routine) (void*) " refers to
my initiation function

void *control_updater (unsigned char rs232_control[10][10]);

The function definition in pthread.h seems to match the start_routine I've described, but the error message seems to find fault with the arguement for the function.

Can anyone find my oversight?


kbw (5520)
You can't change the prototype of a thread entry point. You have to cast.
1
2
3
4
5
6
7
8
9
10
11
12
13
void *control_updater (void* param)
{
    unsigned char *rs232 = reinterpret_cast<unsigned char*>(param);
    unsigned char send_control[10][10];

    while (1)
    {
        memcpy(send_control, rs232_control, 100);
        control_push(send_control);
    }

    return NULL;
}
NanoGoner (26)
I presume that the

*rs232

should have been

*rs232_control.

In any case, I tried both implimentations and got the same error message as before. The casting doesn't seem to have changed anything.
ne555 (4383)
You did change the prototype too, ¿right?

As I already tell you,
1
2
3
4
5
6
7
iret = 
   pthread_create(
      &control_thread, 
      NULL,
      control_updater,
      rs232_control //undeclared
   );


Also, look at line 36.
NanoGoner (26)
I'm reposting the code to incorporate the suggestions so far.
I've also changed variable names to better reflect the test application for the intended code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * Main for PC side of PC generated patterns fed to
 * AVR by UART
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cube.h"
#include "draw.h"
#include "draw_3d.h"
#include "effect.h"
#include "gameoflife.h"
#include <pthread.h>

// The next line should already declare the variable rs232_cube as it declares cube_updater()  
//  as commented by ne555

void *cube_updater (unsigned char rs232_cube[8][8]);    //this declares the variable rs232_cube<-ne555

int main(int argc, char **argv)
{

    cube_init();

    pthread_t cube_thread;
    int iret, i, x;

    iret = pthread_create(&cube_thread, NULL, cube_updater, rs232_cube);      
    
 /*  Note I've modified the variable names in the code from "control" to "cube" to better reflect the current application:
 
 This is the last change suggested from the forum ---   ne555
 
 iret =    pthread_create(&control_thread, ULL, control_updater,rs232_control  )                //undeclared

*/
    while (1)
    {
        printf("Effect: sidewaves\n");                          // sidewaves
        sidewaves(2000,100);

        printf("Effect: ripples\n");                            // ripples
        ripples(2000,100);

        printf("Effect: linespin\n");                           // Linespin
        linespin(2000,100);

        printf("Effect: sinelines\n");                          // Sinelines
        sinelines(2000,100);

        printf("Effect: spheremove\n");                         // Spheremove     
        spheremove(1500,100);                                   // ne555

        printf("Effect: fireworks\n");                          // Fireworks
        fireworks(7,50,1200);

        printf("Effect: gol_play\n");                           // Game of Life
        for (i=0; i<10; i++)
        {
            for (x=0; x<20; x++)
                setvoxel(rand()%4,rand()%4,rand()%4);

            gol_play(50,1000);


        }
    }

}

void *cube_updater (void* param)                       //kbw  suggested revision - same error
{
    unsigned char *rs232_cube = reinterpret_cast<unsigned char*>(param);
    unsigned char pushcube[8][8];

    while (1)
    {
        memcpy(pushcube, rs232_cube, 64);
        cube_push(pushcube)
    }

    return NULL;
}


/*  code before recasting suggestion from the forum - ne555

void *cube_updater (unsigned char rs232_cube[8][8])   // old code with conflict of definition error
{
    unsigned char pushcube[8][8];


    while (1)
    {
        memcpy(pushcube, rs232_cube, 64);
        cube_push(pushcube);
    }
}

*/


All current suggestions result in the same declaration error
Last edited on
ne555 (4383)
You are not listening.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
 * Main for PC side of PC generated patterns fed to
 * AVR by UART
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "cube.h"
#include "draw.h"
#include "draw_3d.h"
#include "effect.h"
#include "gameoflife.h"
#include <pthread.h>

void *cube_updater (void *rs232_cube); //respect this prototype ,because that's what pthread_create() asks for

int main(int argc, char **argv)
{
    cube_init();

    pthread_t cube_thread;
    int iret, i, x;
    unsigned char rs232_cube[8][8]; //create the matrix
    //now you can use `rs232_cube' as it is declared
    iret = pthread_create(&cube_thread, NULL, cube_updater, rs232_cube);
   
    while (1)
    {
        printf("Effect: sidewaves\n");                          // sidewaves
        sidewaves(2000,100);

        printf("Effect: ripples\n");                            // ripples
        ripples(2000,100);

        printf("Effect: linespin\n");                           // Linespin
        linespin(2000,100);

        printf("Effect: sinelines\n");                          // Sinelines
        sinelines(2000,100);

        printf("Effect: spheremove\n");                         // Spheremove     
        spheremove(1500,100);                                   // ne555

        printf("Effect: fireworks\n");                          // Fireworks
        fireworks(7,50,1200);

        printf("Effect: gol_play\n");                           // Game of Life
        for (i=0; i<10; i++)
        {
            for (x=0; x<20; x++)
                setvoxel(rand()%4,rand()%4,rand()%4);

            gol_play(50,1000);
        }
    }

}

void *cube_updater (void* rs232_cube) //the definition should match the prototype
{
    //no need to cast anything
    unsigned char pushcube[8][8];

    while (1)
    {
        memcpy(pushcube, rs232_cube, 64);
        cube_push(pushcube)
    }

    return NULL;
}
Now look at the logic, you never put anything to `rs232_cube' ¿how do you pretend to use it?
NanoGoner (26)
The variable rs_cube[8][8] is loaded in the various "effect..." routines. When it is loaded, the thread picks it up and delivers it to cube_updater() otherwise I must not be understanding something. Even if that weren't the case, I don't understand why that would stand in the way of compiling and linking.
Registered users can post here. Sign in or register to post.