为什么我收到此错误:取消引用指向不完整类型的指针

时间:2011-11-03 19:29:16

标签: c linux scheduling

我正在研究一个类的项目,可能是我们必须实现一个简单的调度程序的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的函数中。

所以基本上,我想知道为什么会出现这个错误?

3 个答案:

答案 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的整个定义可见。