如何修复gcc错误:在void之前预期

 志强旻茜青民 发布于 2023-02-13 17:06

所以我正在编写一个使用pthreads来管理所有IO的点对点聊天客户端,当我编译文件时,gcc给了我错误

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[])
 ^

我的程序的源代码是

#include 
#include 
#include 
#include 
#include 

#include 
#include 
#include 
#include 

#define error(s, e, ...) error_at_line (s, e, __FILE__, __LINE__, __VA_ARGS__)

#include 
#include 
#include 
#include 

#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;
}

alk.. 15

pthread_cleanup_push()最有可能实现为引入开放式大括号的宏,该大括号{期望pthread_cleanup_pop()在相同的上下文中(对应).后者然后服务闭合支架}.*1

看一下代码的预处理器输出(当然还有相应的man-pages和header文件),你会得到启发.


*1这种实施方式,BTW,是我用来训练C编码员的最严格的方式......; - >

1 个回答
  • pthread_cleanup_push()最有可能实现为引入开放式大括号的宏,该大括号{期望pthread_cleanup_pop()在相同的上下文中(对应).后者然后服务闭合支架}.*1

    看一下代码的预处理器输出(当然还有相应的man-pages和header文件),你会得到启发.


    *1这种实施方式,BTW,是我用来训练C编码员的最严格的方式......; - >

    2023-02-13 17:08 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有