In a recent project, I've been struggling to fix this syntax error for the last hour or so; gcc complains about a type mismatch between what it says are two objects of identical type:
../../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);
| ^~~~~~~~~~~
I've played around with things like adding / removing reference or dereference operators, changing some of the signatures for the functions involved to make them more similar to examples I've seen online.
For example, I have tried changing the signature of thread_action_func from typedef void thread_action_func to typedef void (*thread_action_func), and changing the usage of the type in function arguments from thread_action_func * to thread_action_func, but it either complains about the type passed no longer being a function or function pointer, or throws the same error about identical types being mismatched.
I have also tried adding an address-of in front of where the function thread_foreach calls timer_check as an argument, like thread_foreach(&timer_check,...), but the error remained the same as initially.
The relevant functions / prototypes / typedefs are:
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);
}
}
}
All of the results I found by searching for this kind of problem were only similar in one aspect or the other, not close enough to be useful e.g. showing what the example of a function pointer is or an error with pointers to integers or characters.
I would guess this is some obvious syntax mistake which I was too frustrated to notice, but I can't really see clearly what may be causing the issue at the moment.
This error occurs when you redefine a
structtag in a different scope.You have not provided a Minimal Reproducible Example, so we cannot definitively identify where the error is, but it can be that this code in
timer.h:declares
struct threadwith function prototype scope. This defines astructtype only for the duration of the function declaration, which is generally useless.Then, in
timer.c, presumably you include some header that declaresthread_unblock, and this header is included aftertimer.his included (if it is). That header declares its ownstruct threadand uses it in the declaration ofthread_unblock.Since the function
timer_checktakes a parameter of a type that is different from the one used inthread_unblock, the compiler reports they have incompatible types, even though they have the same name (coming from different scopes).To fix that,
timer.hshould include the header that declaresstruct threadbefore it declarestimer_check. Then the parameter declarationstruct thread *threadwill refer to the already visible structure type instead of defining a new one.For illustration, here is code that will reproduce the error: