C无法将函数指针类型识别为相同
C unable to recognise function pointer types as the same
在最近的一个项目中,我在过去一个小时左右的时间里一直在努力修复这个语法错误; 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
作为参数的地方前面添加一个address-of,就像thread_foreach(&timer_check,...)
一样,但错误仍然和最初一样.
相关函数/原型/typedef 是:
thread.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);
}
}
}
我通过搜索此类问题找到的所有结果都只是在某一方面相似,不够接近有用,例如显示函数指针的示例是什么或指向整数或字符的错误。
我猜这是一些明显的语法错误,我太沮丧而没有注意到,但我现在真的看不清楚是什么导致了这个问题。
当您在不同范围内重新定义 struct
标记时会发生此错误。
您没有提供Minimal Reproducible Example,所以我们无法确定错误在哪里,但可能是timer.h
中的这段代码:
void timer_check(struct thread *thread, void *aux);
声明 struct thread
具有函数原型作用域。这只在函数声明期间定义了一个 struct
类型,这通常是无用的。
然后,在timer.c
中,大概你包含了一些声明thread_unblock
的header,而这个header是在包含timer.h
之后包含的(如果这是)。 header 声明自己的 struct thread
并在 thread_unblock
.
的声明中使用它
由于函数 timer_check
采用的参数类型与 thread_unblock
中使用的类型不同,编译器报告它们具有不兼容的类型,即使它们具有相同的名称(即将到来来自不同的范围)。
要解决此问题,timer.h
应在声明 timer_check
之前包含声明 struct thread
的 header。然后参数声明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);
}
在最近的一个项目中,我在过去一个小时左右的时间里一直在努力修复这个语法错误; 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
作为参数的地方前面添加一个address-of,就像thread_foreach(&timer_check,...)
一样,但错误仍然和最初一样.
相关函数/原型/typedef 是:
thread.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);
}
}
}
我通过搜索此类问题找到的所有结果都只是在某一方面相似,不够接近有用,例如显示函数指针的示例是什么或指向整数或字符的错误。
我猜这是一些明显的语法错误,我太沮丧而没有注意到,但我现在真的看不清楚是什么导致了这个问题。
当您在不同范围内重新定义 struct
标记时会发生此错误。
您没有提供Minimal Reproducible Example,所以我们无法确定错误在哪里,但可能是timer.h
中的这段代码:
void timer_check(struct thread *thread, void *aux);
声明 struct thread
具有函数原型作用域。这只在函数声明期间定义了一个 struct
类型,这通常是无用的。
然后,在timer.c
中,大概你包含了一些声明thread_unblock
的header,而这个header是在包含timer.h
之后包含的(如果这是)。 header 声明自己的 struct thread
并在 thread_unblock
.
由于函数 timer_check
采用的参数类型与 thread_unblock
中使用的类型不同,编译器报告它们具有不兼容的类型,即使它们具有相同的名称(即将到来来自不同的范围)。
要解决此问题,timer.h
应在声明 timer_check
之前包含声明 struct thread
的 header。然后参数声明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);
}