【问题标题】:C unable to recognise function pointer types as the sameC无法将函数指针类型识别为相同
【发布时间】:2021-09-18 00:46:47
【问题描述】:

在最近的一个项目中,我在过去一个小时左右一直在努力修复这个语法错误; gcc 抱怨它所说的两个相同类型的对象之间的类型不匹配:

../../devices/timer.c: In function ‘timer_interrupt’:
../../devices/timer.c:181:19: warning: passing argument 1 of ‘thread_foreach’ from incompatible pointer type [-Wincompatible-pointer-types]
  181 |   thread_foreach (timer_check, NULL);
      |                   ^~~~~~~~~~~
      |                   |
      |                   void (*)(struct thread *, void *)
In file included from ../../devices/timer.c:9:
../../threads/thread.h:134:42: note: expected ‘void (*)(struct thread *, void *)’ but argument is of type ‘void (*)(struct thread *, void *)’
  134 | void thread_foreach (thread_action_func *func, void *aux);
      |                      ~~~~~~~~~~~~~~~~~~~~^~~~
../../devices/timer.c: At top level:
../../devices/timer.c:185:1: error: conflicting types for ‘timer_check’
  185 | timer_check (struct thread *thread, void *aux) {
      | ^~~~~~~~~~~
In file included from ../../devices/timer.c:1:
../../devices/timer.h:29:6: note: previous declaration of ‘timer_check’ was here
   29 | void timer_check(struct thread *thread, void *aux);
      |      ^~~~~~~~~~~

我尝试过添加/删除引用或取消引用运算符,更改所涉及函数的一些签名以使其与我在网上看到的示例更加相似。

例如,我尝试将thread_action_func 的签名从typedef void thread_action_func 更改为typedef void (*thread_action_func),并将函数参数中类型的使用从thread_action_func * 更改为thread_action_func,但它要么抱怨传递的类型不再是函数或函数指针,或者抛出相同类型不匹配的相同错误。

我也尝试在函数thread_foreach 调用timer_check 作为参数的前面添加地址,例如thread_foreach(&timer_check,...),但错误与最初相同。

相关的函数/原型/typedef有:

线程.h:

struct thread
  {
    ...
    int64_t block_ticks;
    ...
  };

typedef void thread_action_func (struct thread *t, void *aux);
void thread_foreach (thread_action_func *func, void *aux);

thread.c:

void
thread_foreach (thread_action_func *func, void *aux)
{
  struct list_elem *e;

  ASSERT (intr_get_level () == INTR_OFF);

  for (e = list_begin (&all_list); e != list_end (&all_list);
       e = list_next (e))
    {
      struct thread *t = list_entry (e, struct thread, allelem);
      func (t, aux);
    }
}

timer.h:

void timer_check(struct thread *thread, void *aux);

timer.c:

void
timer_sleep (int64_t ticks) 
{
  int64_t start = timer_ticks ();

  ASSERT (intr_get_level () == INTR_ON);

  struct thread *cur = thread_current();
  cur->block_ticks = ticks;
  enum intr_level old_level = intr_disable ();
  thread_block();

  intr_set_level (old_level);
  thread_yield();
}

static void
timer_interrupt (struct intr_frame *args UNUSED)
{
  ticks++;
  thread_tick ();
  thread_foreach (timer_check, NULL);
}

void 
timer_check (struct thread *thread, void *aux) {
  if (thread->status == THREAD_BLOCKED) {
    thread->block_ticks--;
    if (thread->block_ticks <= 0) {
      thread_unblock(thread);
    }
  }
}

我通过搜索此类问题找到的所有结果都只是在一个方面或另一个方面相似,不够接近以至于没有用处,例如显示函数指针的示例是什么,或者带有指向整数或字符的指针的错误。

我猜这是一些明显的语法错误,我太沮丧了以至于没有注意到,但我现在无法真正清楚地看到可能导致问题的原因。

【问题讨论】:

    标签: c multithreading operating-system function-pointers pintos


    【解决方案1】:

    当您在不同的范围内重新定义 struct 标记时会出现此错误。

    您没有提供Minimal Reproducible Example,因此我们无法确定错误在哪里,但可能是timer.h中的这段代码:

    void timer_check(struct thread *thread, void *aux);
    

    用函数原型范围声明struct thread。这仅在函数声明期间定义了一个struct 类型,这通常是无用的。

    然后,在timer.c 中,大概您包含了一些声明thread_unblock 的标头,并且此标头包含在包含timer.h 之后(如果是的话)。该标头声明了自己的struct thread,并在thread_unblock 的声明中使用它。

    由于函数timer_check 采用的参数类型与thread_unblock 中使用的类型不同,因此编译器报告它们具有不兼容的类型,即使它们具有相同的名称(来自不同的范围)。

    要解决此问题,timer.h 应在声明 timer_check 之前包含声明 struct thread 的标头。那么参数声明struct thread *thread将引用已经可见的结构类型,而不是定义一个新的。

    为了说明,这里是重现错误的代码:

    // struct thread; // Uncommenting this line will elimninate the error.
    
    void foo(struct thread *);
    void bar(void (*)(struct thread *));
    void baz(void)
    {
        bar(&foo);
    }
    

    【讨论】:

    • 嗨,很抱歉回复晚了,没有提供最小可重现示例。这似乎奏效了,所以我认为您正确地发现了错误 - 谢谢。
    猜你喜欢
    • 2022-01-11
    • 2016-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-16
    • 1970-01-01
    相关资源
    最近更新 更多