How to fix gcc error: expected while before void

匿名 (未验证) 提交于 2019-12-03 02:16:02

问题:

So I am writing a peer-to-peer chat client that uses pthreads to manage all the IO and when I compile the file gcc gives me the error

client.c: In function ‘accepted_daemon’: client.c:115:1: error: expected ‘while’ before ‘void’  void *  ^ client.c: In function ‘listen_daemon’: client.c:176:1: error: expected ‘while’ before ‘int’  int main(int argc, char *argv[])  ^ 

The source code for my program is

#include <stdlib.h> #include <string.h> #include <stdint.h> #include <errno.h> #include <assert.h>  #include <unistd.h> #include <pthread.h> #include <readline/readline.h> #include <error.h>  #define error(s, e, ...) error_at_line (s, e, __FILE__, __LINE__, __VA_ARGS__)  #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include <netdb.h>  #define PORT 3248 #define PROMPT "message: "  struct accepted  {   int fd;   struct sockaddr_in addr; };  struct value {   struct accepted *acc;   struct value *nxt; };  pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; struct value *remote = NULL;  void push_remote (struct accepted *acc) {   pthread_mutex_lock (&mutex);   struct value *s = malloc (sizeof *s);   s->acc = acc;   s->nxt = remote;   remote = s;   pthread_mutex_unlock (&mutex); }  void pop_remote (struct accepted *acc) {   pthread_mutex_lock (&mutex);   struct value head = { NULL, remote };   struct value *s = &head;   while (s->nxt->acc != acc)     {       s = s->nxt;       if (s->nxt == NULL)     return;     }   struct value *tmp = s->nxt->nxt;   free (s->nxt);   s->nxt = tmp; }   struct accepted * make_socket (uint32_t s_addr) {   struct accepted *addr = malloc (sizeof *addr);   addr->fd = socket (PF_INET, SOCK_STREAM, 0);   if (addr->fd < 0)     {       free (addr);       return NULL;     }    addr->addr.sin_family = AF_INET;   addr->addr.sin_port = htons (PORT);   addr->addr.sin_addr.s_addr = s_addr;    if (connect (addr->fd, (struct sockaddr *) &addr->addr,             sizeof addr->addr) < 0)     {       free (addr);       return NULL;     }    return addr; }  void * accepted_daemon (void *arg) {   pthread_cleanup_push (free, arg);   struct accepted *args = arg;   pthread_cleanup_push (close, args->fd);   push_remote (args);   pthread_cleanup_push (pop_remote, args);    while (1)     {       char buffer[100];       ssize_t chars = read (args->fd, buffer, sizeof buffer);       if (chars < 0)     {       error (0, errno, "Host %s disconnected",          inet_ntop (AF_INET, arg, buffer, sizeof buffer));       return NULL;     }       write (1, buffer, chars);       write (1, "\n", strlen ("\n") * sizeof (char));     }   return NULL; }  void * initial_connection (void *arg) {   uint32_t host = (uint32_t) arg;   struct accepted *acc = make_socket (arg);   if (acc == NULL)     {       char buffer[100];       error (1, errno, "Failed to connect to host %s",         inet_ntop (AF_INET, arg, buffer, sizeof buffer));     }    while (1)     {       uint32_t nxthost;       read (sock, &nxthost, sizeof nxthost);       if (nxthost == 0)     break;       pthread_t thread;       pthread_create (&thread, NULL, initial_connection, (void *) nxthost);     }    return accepted_daemon (acc); }   void * listen_daemon (void *arg) {   int sock = socket (PF_INET, SOCK_STREAM, 0);   pthread_cleanup_push (close, sock);   struct sockaddr_in addr;   addr.sin_family = AF_INET;   addr.sin_port = htons (PORT);   addr.sin_addr.s_addr = INADDR_ANY;    bind (sock, (struct sockaddr *) &addr, sizeof addr);   listen (sock, 5);    while (1)     {       struct accepted *acc = malloc (sizeof *acc);       socklen_t len;       acc->fd = accept (sock, (struct sockaddr *) &acc->addr, &len);        pthread_mutex_lock (&mutex);       struct value *p = remote;       while (p != NULL)     {       write (acc->fd, &p->acc->addr.sin_addr.s_addr, sizeof (uint32_t));       p = p->nxt;     }       pthread_mutex_unlock (&mutex);        pthread_t thread;       pthread_create (&thread, NULL, accepted_daemon, (void *) acc);     }   return NULL; }   int main(int argc, char *argv[]) {   assert (argc == 2);    struct hostent *target = gethostbyname2 (argv[1], AF_INET);   if (target == NULL)     error (1, errno, "Host could not be found");    pthread_t thread;   pthread_create (&thread, NULL, initial_connection,            (void *) inet_addr (target->h_addr));    pthread_create (&thread, NULL, listen_daemon, NULL);    char *in = readline (PROMPT);   while (in != NULL)     {       pthread_mutex_lock (&mutex);       struct value *p = remote;       while (p != NULL)     {       write (p->addr->fd, in, strlen (in));       p = p->nxt;     }       pthread_mutex_unlock (&mutex);       free (in);       in = readline (PROMPT);     }    return 0; } 

回答1:

pthread_cleanup_push() most likely is implemented as a macro introducing an open brace { which expects a (corresponding) pthread_cleanup_pop() in the same context. The latter then serves the closing brace }. *1

Have a look at the pre-processor output of the code (and into the according man-pages and header files of course) and you'll get enlightened.


*1 This kind of implementation, BTW, is the most rigorous way I ever saw to discipline C coders ... ;->



回答2:

I had the same issue and adding pthread_cleanup_pop(1) solved it.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!