Я реализую реализацию очередей на 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. Я мог бы либо передать -std=gnu89
, либо изменить сигнатуры функций по ссылке выше. Я выбрал второй вариант:
inline queue newQueue(void) {
queue q = { NULL, NULL };
return q;
}
inline bool isEmpty(queue q) {
return q.first == NULL;
}
Но теперь и clang, и gcc что-то говорят о дублированных объявлениях функций при компиляции в режиме c99. Это сопутствующее определение в 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.