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

shu*_*iar 1 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;                
};
Run Code Online (Sandbox Code Playgroud)

我试图在里面调试的功能:

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);
Run Code Online (Sandbox Code Playgroud)

}

最奇怪的是,当我printf(...)在调用上述函数的方法中使用相同的东西时,它可以正常工作,但只是在我seedTask传递的函数中.

基本上,我想知道为什么我会收到此错误?

cni*_*tar 5

这是因为该函数initschedule只看到了声明struct task_struct,而不是它的定义.据推测,调用的函数initschedule已经看到了定义,因此可以取消引用它的指针.

因此initschedule,它是一个不完整的类型,它只能传递指向它的指针,但实际上不能取消引用这些指针.

只需确保包含定义该结构的标头schedule.c.

编辑

这似乎是导致这种情况的另一个不完整的定义:thread_info.这与上面解释的基本问题相同,但您必须包含定义的标头thread_info.


Alo*_*ave 5

为什么会出现此错误:取消引用不完整类型的指针?

您无需添加头文件,而是添加以下行:

struct task_struct;
Run Code Online (Sandbox Code Playgroud)

转发声明了类task_struct,对于编译器来说这是一个不完整的类型。对于不完整类型,不能创建它的变量,也不能执行需要编译器知道仅仅是类型task_struct的事实的布局或其他事情task_struct。即:编译器不知道其成员和内存布局是什么。
但是,由于指向所有对象的指针只需要相同的内存分配,因此当仅将Incomplete类型用作指针时,可以使用前向声明。

请注意,通常在类具有循环依赖的情况下使用前向声明。

对于如何进一步使用不完整类型,前向声明有其自身的局限性。
使用不完整类型,您可以:

  • 声明一个成员作为不完整类型的指针。
  • 声明接受/返回不完整类型的函数或方法。
  • 定义接受/返回不完整类型的指针(但不使用其成员)的函数或方法。

使用不完整类型,您不能:

  • 用它声明一个成员。
  • 使用此类型定义函数或方法。

建议的解决方案:
这里存在问题,因为在函数内部initschedule您尝试访问的成员struct task_struct,即:

(seedTask)->thread_info->processName
Run Code Online (Sandbox Code Playgroud)

因此,这里的编译器需要知道member的定义thread_info。您需要包括定义头struct thread_info在你的schedule.c

为什么在没有错误的情况下起作用schedule.h
因为该头文件仅引用struct thread_info作为指针,而没有引用其成员,而同时引用schedule.c