关于C中内联声明的困惑
我在C中实现队列的实现.我的界面包含五个访问队列的简单函数:
#ifndef QUEUE_H #define QUEUE_H #include <stdbool.h> #include <stddef.h> struct queue { struct cell* first; struct cell* last; }; typedef struct queue queue; extern queue newQueue(void); extern bool isEmpty(queue); extern queue enqueue(queue,void*); extern queue dequeue(queue); extern void* front(queue); extern void freeQueue(queue); 由于其中两个(newQueue和isEmpty)非常简单,我相信编译器可以用它们做很多好的优化,我决定为它们编写内联声明: /* replacing the two lines extern queue newQueue(void); extern bool isEmpty(queue); in the original header */ extern inline queue newQueue(void) { queue q = { NULL,NULL }; return q; } extern inline bool isEmpty(queue q) { return q.first == NULL; } 用gcc编译好.但是当我用clang编译它时,它给了我一个错误.一项快速研究表明,从GNU风格做这些内联声明的官方方式是is different.我可以传递-std = gnu89或根据上面的链接更改功能签名.我选择了第二个选项: inline queue newQueue(void) { queue q = { NULL,NULL }; return q; } inline bool isEmpty(queue q) { return q.first == NULL; } 但是现在,当以c99模式编译时,clang和gcc都会说一些关于重复函数声明的内容.这是queue.c中的附带定义: #include "queue.h" /* ... */ queue newQueue() { queue q = { NULL,NULL }; return q; } bool isEmpty(queue q) { return q.first == NULL; } 我究竟做错了什么?如何在不需要切换到gnu89模式的情况下获得我想要的内容? 这些是我用第二种风格得到的错误消息: $gcc -std=c99 queue.c queue.c:12:7: error: redefinition of ‘newQueue’ queue.h:14:21: note: previous definition of ‘newQueue’ was here queue.c:17:6: error: redefinition of ‘isEmpty’ queue.h:19:20: note: previous definition of ‘isEmpty’ was here $clang -std=c99 queue.c queue.c:12:7: error: redefinition of 'newQueue' queue newQueue() { ^ In file included from queue.c:5: ./queue.h:14:21: note: previous definition is here extern inline queue newQueue(void) { ^ queue.c:17:6: error: redefinition of 'isEmpty' bool isEmpty(queue q) { ^ In file included from queue.c:5: ./queue.h:19:20: note: previous definition is here extern inline bool isEmpty(queue q) { ^ 2 errors generated. 解决方法
如果要在头文件中定义函数,请将它们设为静态.这应该足以让编译器内联它们(内联只是一个额外的提示).
如果在整个程序中包含多个标题,则标题中的非静态函数将导致多个定义. 我做了一些研究并获得了更多信息: 您可以使用内联方式.至少在C99.您不能在queue.c中同时拥有内联和非内联定义.您需要在#ifdef中包装内联定义或将它们移动到queue.c中不包含的头文件中. 您需要编写两次函数并使用预处理器,但它应该完全按照您的意愿工作.当函数未内联时,它只会被发出一次. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |