pthread in c unexpected declaration speifiers or '...' before '(' - c

here is a snippet of a program I've been working on. Basically, I am getting the same error message twice as described by the title. This is my first time working with pthreads so if someone can tell me what I'm doing wrong I'd appreciate it.
#include <pthread.h>
#include <stdio.h>
void *User_choices();
void *Switch_statement(void *);
void *Server_function(void *);
pthread_t SEND_TO_SERVER_THREAD;
pthread_t PIC_COMMUNICATION_THREAD;
pthread_t USER_INTERFACE_THREAD;
char buf[1024];
void main()
{ // 1
snprintf(buf, 1024, "string");
while(1)
{ // 2
pthread_create(&USER_INTERFACE_THREAD, NULL, User_choices, NULL);
} // 3
} // 4
void *User_choices()
{ // 5
int userinput;
printf("Type 0 to reset sensor, 1 to ping, 2 to receive ADC value, 3 to quit the program: ");
scanf("%i", &userinput);
pthread_create(&PIC_COMMUNICATION_THREAD, NULL, Switch_statement, &userinput);
} // 6
void *Switch_statement((void *)userchoice))
{ // 7
int user = (int)*userchoice;
switch(user)
{ // 8
case 1:
printf("OTHER FUNCTIONS USUALLY GO HERE \n");
break;
case 2: //RETRIEVE ADC CASE
pthread_create(&SEND_TO_SERVER_THREAD, NULL, Server_function, (void *)&buffer);
break;
case 3:
exit(0);
case 0: //RESET CASE
printf("ONCE AGAIN, OTHER FUNCTIONS USUALLY GO HERE");
break; //EXIT THE PROGRAM
default:
printf("Your entry is not a valid option! Try again \n");
} // 9
} // 10
void *Server_function((void *)server_buffer))
{ // 11
const char* send_to_server = (char)*server_buffer;
HTTP_GET(send_to_server);
} // 12
Here are the error codes:
justpthread.c:31:24: error: expected declaration specifiers or ‘...’ before ‘(’ token
void *Switch_statement((void *)userchoice))
^
justpthread.c:53:23: error: expected declaration specifiers or ‘...’ before ‘(’ token
void *Server_function((void *)server_buffer))
If I change just void main to int main, I get the same two error codes. If i take out the parentheses surround (void *), no matter when it's int main or void main, i get the following:
justpthread.c: In function ‘Switch_statement’:
justpthread.c:33:18: warning: dereferencing ‘void *’ pointer [enabled by default]
int user = (int)*userchoice;
^
justpthread.c:33:2: error: invalid use of void expression
int user = (int)*userchoice;
^
justpthread.c:41:76: error: ‘buffer’ undeclared (first use in this function)
pthread_create(&SEND_TO_SERVER_THREAD, NULL, Server_function, (void *)&buffer);
^
justpthread.c:41:76: note: each undeclared identifier is reported only once for each function it appears in
justpthread.c:44:5: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
exit(0);
^
justpthread.c: In function ‘Server_function’:
justpthread.c:55:37: warning: dereferencing ‘void *’ pointer [enabled by default]
const char* send_to_server = (char)*server_buffer;
^
justpthread.c:55:2: error: invalid use of void expression
const char* send_to_server = (char)*server_buffer;
^
And you guys have me incredibly confused as far as the brackets go, so I numbered all of them. I'm seeing an even number, and they look like they alter directions properly.
Going off of additional recommendations, I changed my code like so:
void main()
{
snprintf(buf, 1024, "string");
while(1)
{
pthread_create(&USER_INTERFACE_THREAD, NULL, User_choices, NULL);
}
}
void *User_choices()
{
int userinput;
printf("Type 0 to reset sensor, 1 to ping, 2 to receive ADC value, 3 to quit the program: ");
scanf("%i", &userinput);
pthread_create(&PIC_COMMUNICATION_THREAD, NULL, Switch_statement, &userinput);
}
void *Switch_statement(void *userchoice)
{
int user = *((int*)userchoice);
switch(user)
{
case 1:
printf("OTHER FUNCTIONS USUALLY GO HERE \n");
break;
case 2: //RETRIEVE ADC CASE
pthread_create(&SEND_TO_SERVER_THREAD, NULL, Server_function, (void *)&buf);
break;
case 0: //RESET CASE
printf("ONCE AGAIN, OTHER FUNCTIONS USUALLY GO HERE");
break; //EXIT THE PROGRAM
default:
printf("Your entry is not a valid option! Try again \n");
}
}
I changed int user... to
int user = *((int*)userchoice);
as recommended, and so I got the following error messages:
justpthread.c: In function ‘Server_function’:
justpthread.c:53:37: warning: dereferencing ‘void *’ pointer [enabled by default]
const char* send_to_server = (char)*server_buffer;
^
justpthread.c:53:2: error: invalid use of void expression
const char* send_to_server = (char)*server_buffer;
So it looks like it got rid of some of the previous errors. So I noticed now that server_buffer is having issues as well so I tried to change that to:
void *Server_function(void *server_buffer)
{
const char* send_to_server = *((char*)server_buffer);
//HTTP_GET(send_to_server);
}
And now I just have one error:
justpthread.c: In function ‘Server_function’:
justpthread.c:53:31: warning: initialization makes pointer from integer without a cast [enabled by default]
const char* send_to_server = *((char*)server_buffer);

For the last warning, you want to cast void* to char*, but with *((char*)server_buffer you are dereferencing pointer to server_buffer and casting void* to char and not to char*.
The proper way is:
const char* send_to_server = (char*)server_buffer;

Remove the (parenthesis) around void * on those lines.

Try void *userchoice and
int user = *((int*)userchoice);
You cannot do anything with void * before you cast it.

Related

Getting warning of passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types]

I am running the below code and it is working fine but still it is giving some warning which i don't understand. Can someone please explain this to me ? Thanks
#include <stdio.h>
#include <pthread.h>
void* the_thread_func(double data_for_thread[]) {
/* Do something here? */
for(int i=0;i<3;i++){
double sum = sum + data_for_thread[i];
printf("The sum done by the_thread_func() is = %f\n",sum);
}
return NULL;
}
int main() {
printf("This is the main() function starting.\n");
double data_for_thread[3];
data_for_thread[0] = 5.7;
data_for_thread[1] = 9.2;
data_for_thread[2] = 1.6;
/* Start thread. */
pthread_t thread;
printf("the main() function now calling pthread_create().\n");
pthread_create(&thread, NULL, the_thread_func, data_for_thread);
printf("This is the main() function after pthread_create()\n");
/* Do something here? */
for(int i=0;i<3;i++){
double sum = sum + data_for_thread[i];
printf("The sum done by main() is = %f\n",sum);
}
/* Wait for thread to finish. */
printf("the main() function now calling pthread_join().\n");
pthread_join(thread, NULL);
return 0;
}
warning: passing argument 3 of ‘pthread_create’ from incompatible pointer type [-Wincompatible-pointer-types] pthread_create(&thread, NULL, the_thread_func, data_for_thread);
^~~~~~~~~~~~~~~
In file included from thread_data.c:2:0:
/usr/include/pthread.h:234:12: note: expected ‘void * (*)(void *)’ but argument is of type ‘void * (*)(double *)’
extern int pthread_create (pthread_t *__restrict __newthread,
According to the manual pthread_create needs to be given a function with this signature:
void* (*start_routine)(void*)
But you are passing it a function that accepts double*here:
void* the_thread_func(double data_for_thread[]) // decays to double*
I think you need to change the signature and cast the void*inside the function like this:
// accept void*
void* the_thread_func(void* vp) {
/* Do something here? */
double* data_for_thread = reinterpret_cast<double*>(vp); // cast here
for(int i=0;i<3;i++){
double sum = sum + data_for_thread[i];
printf("The sum done by the_thread_func() is = %f\n",sum);
}
return nullptr;
}

Error while implementing a complex construct in C < char (*(*f())[]) () >

Error while implementing a complex construct in C.
Here is the piece of snippet I had tried.
'Where f is a function returning a pointer to an array of
pointers pointing to a function returning character.'
#include <stdio.h>
int main()
{
char (*(*f())[]) ();
char s ()
{
return 'y';
}
char (*g[1])();
g[0] = s;
printf("%c\n",g[0]());
// here it's throwing error how to fix it?**strong text**
(char (*(*)[])()) func()
{
return g;
}
f = func;
printf("%c\n",(f())[0]());
return 0;
}
Error:
enter code heremain.c: In function ‘main’:
main.c:27:19: warning: implicit declaration of function ‘func’ [-Wimplicit-function-declaration]
(char (*(*)[])()) func()
^~~~
main.c:27:1: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
(char (*(*)[])()) func()
^
main.c:28:1: error: expected ‘;’ before ‘{’ token
{
^
main.c:33:1: error: invalid use of array with unspecified bounds
printf("%c\n",(f())[0]());
^~~~~~
main.c:33:16: error: called object is not a function or function pointer
printf("%c\n",(f())[0]());
Use typedefs to help:
#include <stdio.h>
typedef char (*functionPtr)(void);
typedef char (**arrayOfFunctionPtr)(void);
// OR THIS
// typedef functionPtr* arrayOfFunctionPtr;
typedef arrayOfFunctionPtr (*functionReturningArrayOfFunctionPointers)(void);
int main()
{
functionReturningArrayOfFunctionPointers f;
char s()
{
return 'y';
}
char (*g[1])();
g[0] = s;
printf("%c\n",g[0]());
arrayOfFunctionPtr func()
{
return g;
}
f = func;
printf("%c\n",(f())[0]());
return 0;
}

Using function pointer array in pthread_create - near initialization

EDIT: This has been answered with the help of John Bollinger and alk. Read their comments below! I've also included my revised code at the bottom on this original post for anyone searching to read
I'm trying to use an array of function pointers to send as the function argument in pthread_create but when I try to compile (using: "gcc -std=c99 P1.c -lpthread" I am getting the following errors:
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
func_ptr funcs[4] = {func0, func1, func2, func3};
P1.c:40:1: warning: (near initialization for 'funcs[0]') [enabled by default]
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
P1.c:40:1: warning: (near initialization for 'funcs[1]') [enabled by default]
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
P1.c:40:1: warning: (near initialization for 'funcs[2]') [enabled by default]
P1.c:40:1: warning: initialization from incompatible pointer type [enabled by default]
P1.c:40:1: warning: (near initialization for 'funcs[3]') [enabled by default]
I think it's an issue with my typedef declaration of my function pointer but I'm having trouble figuring out exactly what the issue is. Below is the relevant code snippet:
void func0()
{ printf("A"); }
void func1()
{ printf("B"); }
void func2()
{ printf("C"); }
void func3()
{ printf("D"); }
typedef void* (*func_ptr)(void *);
func_ptr funcs[4] = {func0, func1, func2, func3};
int main(int argc, char *argv[])
{
pthread_t pth[THREADCNT];
for(int i =0; i < THREADCNT; i++)
pthread_create(&pth[i], NULL, (funcs[i])(), NULL);
for(int i =0; i < THREADCNT; i++)
pthread_join(pth[i], NULL);
}
REVISED WORKING CODE BELOW
// changed these functions to void* with (void * pv) parameter to
// match the typedef (and also match the pthread_create parameter)
void* func0(void * pv)
{ printf("A"); }
void* func1(void * pv)
{ printf("B"); }
void* func2(void * pv)
{ printf("C"); }
void* func3(void * pv)
{ printf("D"); }
typedef void* (*func_ptr)(void *);
func_ptr funcs[4] = {func0, func1, func2, func3};
int main(int argc, char *argv[])
{
pthread_t pth[THREADCNT];
for(int i =0; i < THREADCNT; i++)
pthread_create(&pth[i], NULL, funcs[i], NULL);
// changed the funcs[i] because the function isn't called, the value is just passed as an argument
for(int i =0; i < THREADCNT; i++)
pthread_join(pth[i], NULL);
}
Change
void func0()
to be
void * func0(void * pv)
(same for the other three)
because that's the type the array is defined to hold, as well as the type pthread_create() expects.
Change
pthread_create(&pth[i], NULL, (funcs[i])(), NULL);
to be
pthread_create(&pth[i], NULL, funcs[i], NULL);
as you do not want to call funcs[i] but pass its value.

not sure what's going on in this code

I have some C code, and I'm not quite sure what's going on.
#include <stdio.h>
#include <stdlib.h>
#define DIM1 7
#define DIM2 5
#define RES_SIZE 1000
typedef double stackElementT;
typedef struct {
stackElementT *contents;
int maxSize;
int top;
int min2;
} stackT;
void StackInit(stackT *stackP, int maxSize) {
stackElementT *newContents;
newContents = (stackElementT *)malloc(sizeof(stackElementT)*maxSize);
if (newContents == NULL) {
fprintf(stderr, "Not enough memory.\n");
exit(1);
}
stackP->contents = newContents;
stackP->maxSize = maxSize;
stackP->top = -1;
}
void StackDestroy(stackT *stackP) {
free(stackP->contents);
stackP->contents = NULL;
stackP->maxSize = 0;
stackP->top = -1;
}
int StackIsEmpty(stackT *stackP) { return stackP->top < 0; }
int StackIsFull(stackT *stackP) { return stackP->top >= stackP->maxSize-1; }
void StackPush(stackT *stackP, stackElementT element) {
if(StackIsFull(stackP)) {
fprintf(stderr, "Can't push element: stack is full.\n");
exit(1);
}
stackP->contents[++stackP->top] = element;
}
stackElementT StackPop(stackT *stackP) {
if(StackIsEmpty(stackP)) {
fprintf(stderr, "Can't pop element: stack is empty.\n");
exit(1);
}
return stackP->contents[stackP->top--];
}
int shell(char* s1, int arg) {
printf("> ");
scanf("%s %d%*c", &s1, &arg);
return arg;
}
int main() {
char cmds[DIM1][DIM2] = {{"push"}, {"pop"}, {"add"}, {"ifeq"}, {"jump"}, {"print"}, {"dup"}};
char* s1; int arg;
arg = shell(s1, arg);
printf("%s\n", &s1);
}
Input: push 4. It prints J+ instead of "push" but prints 4 normally.
It also gives these warnings on compile:
stack.c: In function ‘shell’:
stack.c:60: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
stack.c: In function ‘main’:
stack.c:71: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
stack.c:65: warning: unused variable ‘cmds’
stack.c:69: warning: ‘arg’ is used uninitialized in this function
Can someone please explain?
When you use the %s format specifier, it expect a value which is a pointer to the start of a string. In C, this type is char *.
Taking your main function, your variable s1 is of type char *. Therefore, s1 is a valid parameter to printf, so this line is valid:
printf("%s\n", s1);
Note the absence of an & in front of s1. In your code, you used the &, which takes the address of s1, the result of which will be of type char **. This is the wrong type, so don't use the &.
The thing is, printf can't actually tell what type its arguments are, since it is a variadic function. It simply uses whatever arguments are there, according to the types specified in the format string.
The same thing goes for scanf, but there is a pitfall: you must make sure that enough memory is allocated to account for the user input, else you will experience a buffer overflow with unpredictable results. Aside from this, printf and scanf are perfectly complementary.
Anyhoo, this takes care of the compiler warnings, aside from the unused cmds variable (it's unnecessary in the provided code). Also, there is the part of args - it really should be a variable declared inside of shell, and not passed as a parameter, since its value is not even used inside shell.
Don't know what's up with the rest of the code. It's superfluous considering your main function only calls on shell.

C code works on Windows (compiled with Visual Studio) but won't compile on Linux (using gcc)

I am currently trying to make a very simple C program for school that creates an array of m integer n (both of which are defined by user input) and either returns the location of the starts of the array or an error message if the array could not be created. It works perfectly well when compiled using Visual Studio, but when I tried to compile it using gcc it throws me a heap of error messages and I simply have no idea what is causing them.
Source code:
#include <stdio.h>
int *create_array(int n, int initial_value);
int main(){
int *arr;
int num;
int numOfNum;
printf("Store this integer:\n");
scanf("%d", &num);
printf("Store the integer this amount of time:\n");
scanf("%d", &numOfNum);
arr = create_array(num, 1);
if(arr == NULL) printf("ERROR");
else printf("Array stored in this location: %p", arr);
return 0;
}
int *create_array(int n, int initial_value){
int *pointer;
int i;
pointer = (int *) malloc(sizeof(int) * 10);
for(i = 0; i < n; i++){
int *p;
p = pointer;
p += n*(sizeof(int));
*p = initial_value;
}
return pointer;
}
Error from gcc:
q1.c: In function âmainâ:
q1.c:18: error: missing terminating " character
q1.c:19: error: ânotâ undeclared (first use in this function)
q1.c:19: error: (Each undeclared identifier is reported only once
q1.c:19: error: for each function it appears in.)
q1.c:19: error: expected â)â before âbeâ
q1.c:19: error: missing terminating " character
q1.c:20: error: missing terminating " character
q1.c:21: error: missing terminating " character
q1.c:39: error: expected declaration or statement at end of input
Seeing the weird characters "ânotâ" I suspect that you are using a bad file encoding. Try copy pasting the code into a linux file editor and save it from that editor into a new file. Try compiling that.
Your code, exactly as you posted it, generates these messages with my gcc
6398652.c:4:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
6398652.c: In function ‘main’:
6398652.c:4:5: error: old-style function definition [-Werror=old-style-definition]
6398652.c:18:3: error: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘int *’ [-Werror=format]
6398652.c: In function ‘create_array’:
6398652.c:25:3: error: implicit declaration of function ‘malloc’ [-Werror=implicit-function-declaration]
6398652.c:25:21: error: incompatible implicit declaration of built-in function ‘malloc’ [-Werror]
cc1: all warnings being treated as errors
This changed version compiles cleanly
#include <stdio.h>
#include <stdlib.h>
int *create_array(int n, int initial_value);
int main(void) {
int *arr;
int num;
int numOfNum;
printf("Store this integer:\n");
scanf("%d", &num);
printf("Store the integer this amount of time:\n");
scanf("%d", &numOfNum);
arr = create_array(num, 1);
if (arr == NULL) {
printf("ERROR\n");
} else {
printf("Array stored in this location: %p\n", (void*)arr);
}
return 0;
}
int *create_array(int n, int initial_value) {
int *pointer;
int i;
pointer = malloc(10 * sizeof *pointer);
for (i = 0; i < n; i++) {
int *p;
p = pointer;
p += n*(sizeof *p);
*p = initial_value;
}
return pointer;
}

Resources