【问题标题】:How to fix gcc error: expected while before void如何修复 gcc 错误:在 void 之前预期
【发布时间】:2013-12-16 17:57:54
【问题描述】:

所以我正在编写一个点对点聊天客户端,它使用 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 <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;
}

【问题讨论】:

  • 这是正确的代码。我的机器上出现同样的错误。
  • 宏应该有像error这样的通用(和小写)名称。要求 gcc 只预处理代码而不编译它(gcc file -E &gt; tempfile)并检查 accepted_daemon 之前的函数,以确保宏正在按照您认为的方式扩展。
  • 错误在哪几行? 叹息
  • 我的代码只有一个文件,就是这个。
  • @DCoder 我的error 宏旨在屏蔽另一个功能。它主要用于帮助调试。

标签: c gcc compiler-errors pthreads


【解决方案1】:

pthread_cleanup_push() 很可能被实现为一个宏,它引入了一个左大括号{,它在相同的上下文中需要一个(对应的)pthread_cleanup_pop()。然后后者服务于右括号}*1

看看代码的预处理器输出(当然还有相应的手册页和头文件),你会得到启发。


*1 这种实现方式,顺便说一句,是我见过的最严格的 C 编码人员训练方式... ;->

【讨论】:

    猜你喜欢
    • 2020-11-16
    • 1970-01-01
    • 1970-01-01
    • 2020-01-21
    • 1970-01-01
    • 2012-10-04
    • 1970-01-01
    • 2018-06-28
    • 2020-12-05
    相关资源
    最近更新 更多