我正在研究一个类的项目,可能是我们必须实现一个简单的调度程序的WORST指令..虽然C编程不是课程的先决条件,这是调度程序的语言,我不是必然是C程序员..
无论如何,我试图通过打印任务来调试它,以便我可以通过程序跟踪它,但我不断收到以下编译时错误:
schedule.c:61:48:error:解除引用指向不完整类型的指针
这是task_struct
定义:
struct task_struct
{
struct thread_info *thread_info;
int prio, static_prio, normal_prio;
unsigned long sleep_avg;
unsigned long long last_ran;
unsigned long long timestamp;
unsigned long long sched_time;
unsigned int time_slice, first_time_slice;
struct list_head run_list;
struct sched_array *array;
enum sleep_type sleep_type;
int need_reschedule;
};
我试图在里面调试的功能:
void initschedule(struct runqueue *newrq, struct task_struct *seedTask)
{
printf("Inside initschedule()\n");
printf("%s - TEST \n", (seedTask)->thread_info->processName); //causes compiler error
/* initialize runqueue and current task */
rq = newrq;
current = NULL;
/* allocate memory for runqueue schedule arrays */
rq->active = (struct sched_array*)malloc(sizeof(struct sched_array));
rq->expired = (struct sched_array*)malloc(sizeof(struct sched_array));
/* initialize schedule arrays */
INIT_LIST_HEAD(&rq->active->list);
INIT_LIST_HEAD(&rq->active->list);
/* activate task in scheduler */
activate_task(seedTask);
}
最奇怪的是,当我在调用上述函数的方法中使用相同的printf(...)
时,它可以正常工作,但不在我传递seedTask
的函数中。
所以基本上,我想知道为什么会出现这个错误?
答案 0 :(得分:5)
这是因为函数initschedule
只看到了struct task_struct
,而非其定义的声明。据推测,调用initschedule
的函数已经看到了定义,因此可以取消引用它的指针。
因此,对于initschedule
,它是一个不完整的类型,它只能传递指针,但实际上不能取消引用这些指针。
请确保在schedule.c
中包含定义该结构的标头。
这似乎是导致这种情况的另一个不完整的定义:thread_info
。这与上面解释的基本问题相同,但您必须包含定义thread_info
的标题。
答案 1 :(得分:5)
为什么我收到此错误:取消引用指向不完整类型的指针?
您可以添加以下行来代替包含头文件:
struct task_struct;
转发声明类task_struct
,这意味着对于编译器来说,它是不完整类型。对于不完整类型,无法创建它的变量或执行任何需要编译器知道task_struct
的布局或更多task_struct
只是一种类型的事实。
即:编译器不知道它的成员是什么以及它的内存布局是什么
但由于指向所有对象的指针只需要相同的内存分配,因此只需将不完整类型作为指针进行处理即可使用前向声明。
请注意,前向声明通常用于存在类的循环依赖性的情况。
前瞻声明对如何进一步使用不完整类型有其自身的局限性 对于不完整类型,您可以:
对于不完整类型,您不能:
提议的解决方案:
这里的问题是因为函数initschedule
内部您尝试访问struct task_struct
的成员,即:
(seedTask)->thread_info->processName
所以这里的编译器需要知道成员thread_info
的定义。您需要在struct thread_info
中包含定义schedule.c
的标头。
为什么它在schedule.h
中没有错误地工作?
因为该头文件仅引用struct thread_info
作为指针而不引用其成员,而schedule.c
则表示。
答案 2 :(得分:1)
当您定义initschedule
时,task_struct
仍然是不完整的类型。在编译struct task_struct
时,您需要确保initschedule
的整个定义可见。