GCC warns me of passing void function to thrd_start_t - c

EDIT: The issue was solved by changing the function type to int!
I am making a test program for multithreading using the threads.h library on Linux using the GCC compiler. I have been recommended by websites to use void when creating the function that a thread will use. However, using the void type results in one warning and one note: main.c:6:28: warning: passing argument 2 of 'thrd_create' from incompatible pointer type [-Wincompatible-pointer-types] and /usr/include/threads.h:79:53: note: expected 'thread_start_t' {aka 'int(*) (void*)} but argument is of '(void*)()'. I have three source files:
main.c:
// . . .
int main() {
thrd_t job1;
thrd_create(&job1, tjob1, NULL);
thrd_join(job1, NULL);
// . . .
jobs.h:
void tjob1();
void tjob2();
void tjob3();
and jobs.c:
// . . .
void tjob1(void) {
system("date");
printf("Doing jobs...");
for(int i = 0; i < 50; i++) {
system("date");
}
}
// . . .
Should I be concerned about the note and warning and how do I fix it? I have tried making tjob1 an int void, which threw an error, and I have tried fixing tjob1 to *tjob1 / &tjob1, which also resulted in errors. I have tried figuring out the ideal type for tjob1 and how to declare a function to be int(*) (void*), but with no luck, as that is what thrd_start_t accepts.
Thank you in advance

thrd_start_t is a typedef for int(*)(void*) which means that your thread starting function, tjob1, has the wrong signature. Since you obviously do not care about the argument passed to it (NULL) or the return value, this rewrite should suffice:
int tjob1(void *dummy) { // correct return type and argument
(void)dummy; // to quiet warnings about unused variables
system("date");
printf("Doing jobs...");
for(int i = 0; i < 50; i++) {
system("date");
}
return 0; // something has to be returned
}

Related

Compiling error invalid operands to binary && (have 'int' and 'pthread_t' {aka 'struct <anonymous>'})

I am trying to compile some C code and I get this error
error: invalid operands to binary && (have 'int' and 'pthread_t' {aka 'struct "<"anonymous>'})
the code in question is
static void kill_mining(void)
{
struct thr_info *thr;
int i;
forcelog(LOG_DEBUG, "Killing off mining threads");
/* Kill the mining threads*/
for (i = 0; i < mining_threads; i++) {
pthread_t *pth = NULL;
thr = get_thread(i);
if (thr && PTH(thr) != 0L)
pth = &thr->pth;
thr_info_cancel(thr);
if (pth && *pth) <---- This is where it goes wrong
pthread_join(*pth, NULL);
}
}
I don't know C so I'm a bit lost on how to fix this. Any help would be appriciated.
Thanks
Edit: Code comes from https://github.com/ckolivas/cgminer and its the cgminer.c file.
Given
pthread_t *pth;
dereferencing the pth value with
if (pth && *pth)
is wrong.
pthread_t is defined under POSIX in sys/types.h:
The <sys/types.h> header shall define at least the following types:
.
.
.
pthread_t
Used to identify a thread.
.
.
.
with the added caveat
All of the types shall be defined as arithmetic types of an appropriate length, with the following exceptions:
.
.
.
pthread_t
.
.
.
It is improper and wrong to treat a pthread_t variable as an object that can be evaluated as part of a boolean expression.

C - Change variables values from a structure in a void* function

I have an exercise to do for school in C where I can't change the content of the main function and the type and parameters of the two others functions. I have searched Google already but found no answers my problem that I did understand.
The goal is simply to display the content of the structure with printf but I have an erreur due to not knowing how to return the structure to the main function.
This is the code :
void *create_mage(t_character *perso)
{
if ((perso = malloc(sizeof(t_character))) == NULL)
exit(84);
perso->niveau = 1;
perso->pdv = 100;
perso->mana = 200;
perso->attaque = 40;
perso->defense = 3;
perso->crit_chance = 10;
perso->vitesse = 4;
return (perso);
}
void *create_warrior(t_character *perso)
{
if ((perso = malloc(sizeof(t_character))) == NULL)
exit(84);
perso->niveau = 1;
perso->pdv = 200;
perso->mana = 50;
perso->attaque = 10;
perso->defense = 8;
perso->crit_chance = 10;
perso->vitesse = 3;
return (perso);
}
int main()
{
t_character p_ava;
t_character p_thi;
p_ava = create_mage(&p_ava);
p_thi = create_warrior(&p_thi);
printf("def %d - atk %d - vit %d - crit %d\n", p_ava.defense,
p_thi.attaque, p_ava.vitesse, p_thi.crit_chance);
return (0);
}
This is the error I get when I compile my project :
gcc *.c -Wall -Wextra
create_class.c: In function ‘main’:
create_class.c:48:9: error: incompatible types when assigning to type ‘t_character {aka struct s_character}’ from type ‘void *’
p_ava = create_mage(&p_ava);
^
create_class.c:49:9: error: incompatible types when assigning to type ‘t_character {aka struct s_character}’ from type ‘void *’
p_thi = create_warrior(&p_thi);
^
I do not have a good concept of how structures work and did not found anything concerning returning structures from void* functions so if you have an answer or a link where I could find one to my problem it would be very welcomed. Thank you in advance !
If you cannot change main, you cannot compile your code -- period (see comment by J. Leffler, above). However, if "change" means you "cannot add to", then you are OK. Why?
All you really need to do is to declare a struct (or better simply declare a typedef of the required structure as t_character) outside of main, and then within main remove p_ava = and p_thi = and remove the calls to malloc in each of your functions and you are fine.
Why? When you declare your structures:
t_character p_ava;
t_character p_thi;
You have created storage for a type t_character for each variable. The compiler simply needs to know what that type is. So you define the t_character struct (or typdef) and your compiler will provide adequate storage for the variables, e.g.
typedef struct {
int niveau, pdv, mana, attaque, defense, crit_chance, vitesse;
} t_character;
When you pass the variables to your functions (e.g. create_mage(&p_ava);) you are passing the address of p_ava to your function. There is already adequate storage created for a t_character at that address. So all you need to do in your functions is validate that you have a valid address for your variable passed to the function, and then just fill the member values for the struct.
Putting those pieces together, you could (not 'change', but 'remove') and do the following:
#include <stdio.h>
#include <stdlib.h> /* for exit() */
typedef struct {
int niveau, pdv, mana, attaque, defense, crit_chance, vitesse;
} t_character;
void *create_mage (t_character *perso)
{
if (!perso) {
fprintf (stderr, "create_mage() error: invalid parameter.\n");
exit (84);
}
perso->niveau = 1;
perso->pdv = 100;
perso->mana = 200;
perso->attaque = 40;
perso->defense = 3;
perso->crit_chance = 10;
perso->vitesse = 4;
return (perso);
}
void *create_warrior (t_character * perso)
{
if (!perso) {
fprintf (stderr, "create_warrior() error: invalid parameter.\n");
exit (84);
}
perso->niveau = 1;
perso->pdv = 200;
perso->mana = 50;
perso->attaque = 10;
perso->defense = 8;
perso->crit_chance = 10;
perso->vitesse = 3;
return (perso);
}
int main (void)
{
t_character p_ava;
t_character p_thi;
create_mage (&p_ava);
create_warrior (&p_thi);
printf ("def %d - atk %d - vit %d - crit %d\n", p_ava.defense,
p_thi.attaque, p_ava.vitesse, p_thi.crit_chance);
return 0;
}
note: you can get rid of the fprint statements and the test for the valid pointers as that 'change' was a matter of habit to validate function parameters, but is not necessary to the successful operation of the functions.
Compile
$ gcc -Wall -Wextra -pedantic -std=gnu11 -Ofast -o bin/magewarrior magewarrior.c
Example Use/Output
$ ./bin/magewarrior
def 3 - atk 10 - vit 4 - crit 10
Look things over and let me know if you have any questions. If you cannot get away with remove, you are pretty much up a creek without a paddle...
Your alternative is to make p_ava and p_thi pointers as noted in the comments (replacing the '.' operator with the '->' arrow operator in your printf), then you can allocate with malloc within the functions, but will receive a warning for passing p_ava and p_thi uninitialized, unless the pointers are initialized NULL before calling:
p_ava = create_mage (p_ava);
This would require more change to main than the alternative, e.g.
int main (void)
{
t_character *p_ava = NULL;
t_character *p_thi = NULL;
p_ava = create_mage (p_ava);
p_thi = create_warrior (p_thi);
printf ("def %d - atk %d - vit %d - crit %d\n", p_ava->defense,
p_thi->attaque, p_ava->vitesse, p_thi->crit_chance);
return 0;
}
You will have to do one or the other.

I am running into "error: expected expression before ‘Matrix’ " in C and can't figure out what is wrong

I am trying to add the Matrix*partiklar into my update_boids function so that I can use the values that I have saved in a struct earlier in the main function. I am bashing my head against this error as I can’t understand where it’s coming from. Could you please help me understand how to solve this?
I am quite new to C and am using gcc with the SDL library installed on my machine for the graphics.
I get this compiler error:
main.c: In function ‘main’:
main.c:123:20: error: expected expression before ‘Matrix’
make: *** [main] Error 1
Which points to these lines of code:
update_boids(Matrix *partiklar);
With Matrix defined as follows:
typedef struct Matrix
{
double MatX;
double MatY;
double MatZ;
} Matrix;
And partiklar like:
Matrix partiklar[NR_BIRDS];
Matrix hastighet[NR_BIRDS];
Matrix *p[NR_BIRDS];
Matrix *v[NR_BIRDS];
int t = 0;
while(t<NR_BIRDS)
{
partiklar[t].MatX = rand()%100;
partiklar[t].MatY = rand()%100;
partiklar[t].MatZ = rand()%100;
p[t] = &partiklar[t];
hastighet[t].MatX = rand()%10;
hastighet[t].MatY = rand()%10;
hastighet[t].MatZ = rand()%10;
v[t] = &hastighet[t];
/*printf("%f\n", partiklar[t].MatX);
printf("%f\n", partiklar[t].MatY);
printf("%f\n", partiklar[t].MatZ); */
t++;
}
The line the error points to looks like a function prototype with an implicit return type of int. If it is a function CALL, then you need to leave off the type (the compiler already knows it from wherever partiklar was declared).

sqlite3 library undefined reference error

I am creating a word list searcher in C for my program using sqlite3 but I've got these errors .
I tried whatever I knew but it didn't fixed. I guess the problem is in my join function but I am not sure.
code :
bool *gb_wordlist_add_to_list (gbwordlist *word_list,char *str)
{
int sql_error;
char *error_massage;
if (gb_wordlist_in_list (word_list,str))
{
sql_error = sqlite3_execute(word_list->database, gb_wordlist_join(ADD_TO_TABLE_COMMAND"\'",str,"\';"),
NULL ,NULL, &error_massage);
if( sql_error!=SQLITE_OK )
{
fprintf(stderr, "SQL error: %s\n", error_massage);
sqlite3_free(error_massage);
return 0;
}
}
else
return 0;
}
char *gb_wordlist_join (char *s1,char *s2,char *s3){
char *s;
s = malloc(strlen(s1) + strlen(s2) + strlen(s3) + 1);
if(s)
{
strcpy(s,s1);
strcat(s,s2);
strcat(s,s3);
}
return s;
}
error:
gb-sql.o: In function `gb_wordlist_remove_from_list':
/home/reza/Project/GB/Search algorithm/Source/gb-search/src/gb-sql.c:104: undefined reference to `sqlite3_execute'
Also my full codes are here. Thanks a lot!
The reason you are getting undefined reference to sqlite3_execute is well there is no such function as part of library. You probably meant to use sqlite3_exec (which use have used in some parts of the code).
Side Notes:
The function gb_wordlist_callback is returning int but has been declared to return int*. You should change the return type to int to match the expected parameters to be passed to sqlite3_exec(after modifying from sqlite3_execute)
The 4th parameter passed to sqlite3_exec (after modifying from sqlite3_execute) is expected to be void* so existance should be &existance
You have quite a few functions with mismatch between return type declared and the actual return type returned from the function.
Compile your code with -Wall -Wextra compiler options & fix all the warnings. It is good practice.
Hope this helps!

defining unused parameters in C

I need to use pthreat but I dont need to pass any argument to the function. Therefore, I pass NULL to the function on pthread_create. I have 7 pthreads, so gcc compiler warns me that I have 7 unsued parameters. How can I define these 7 parameters as unused in C programming? If I do not define these parameters as unused, would it cause any problem? Thank you in advance for the responses.
void *timer1_function(void * parameter1){
//<statement>
}
int main(int argc,char *argv[]){
int thread_check1;
pthread_t timer1;
thread_check1 = pthread_create( &timer1, NULL, timer1_function, NULL);
if(thread_check1 !=0){
perror("thread creation failed");
exit(EXIT_FAILURE);
}
while(1){}
return 0;
}
You can cast the parameter to void like this:
void *timer1_function(void * parameter1) {
(void) parameter1; // Suppress the warning.
// <statement>
}
GCC has an "attributes" facility that can be used to mark unused parameters. Use
void *timer1_function(__attribute__((unused))void *parameter1)
Two commonly used techniques:
1) Omit the name of the unused parameter:
void *timer1_function(void *) { ... }
2) Comment out the parameter name:
void *timer1_function(void * /*parameter1*/) { ... }
-- Chris
By default, GCC does not produce this warning, not even with -Wall. I think the workaround shown in other question might be needed when you have no control over the environment, but if you do, just remove the flag (-Wunused-parameter).
It is perfectly fine not using a parameter in a function body.
To avoid the compiler warning (if any in your implementation), you can do this:
void *timer1_function(void * parameter1)
{
// no operation, will likely be optimized out by the compiler
parameter1 = parameter1;
}

Resources