main.c
#include "stackg.h"
int main()
{
return 0;
}
stackg.h
#ifndef STACKG_H
#define STACKG_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct stack_gt* stack_gt;
stack_gt stkg_init(
void* (*alloc)(const void* data, const int size),
void (*dealloc)(void* data),
void (*copy)(void* data_d, const void* data_s),
const int size
);
void stkg_free(stack_gt s);
int stkg_is_empty(stack_gt s);
int stkg_is_full(stack_gt s);
const int stkg_size(const stack_gt s);
void stkg_clear(stack_gt s);
int stkg_push(stack_gt s, const void* data);
int stkg_pop(stack_gt s, void* data);
int stkg_peek(stack_gt s, void* data);
#ifdef __cplusplus
}
#endif
#endif
Вышеуказанная программа успешно компилируется с помощью компилятора GCC, но в MSVC2008 выдает следующую ошибку:
error C2040: 'stack_gt *' differs in levels of indirection from 'stack_gt'
Что я должен сказать MSVC, чтобы он скомпилировал программу, не меняя ничего в коде?
Ошибка возникает в строке 8 stackg.h
:: typedef struct stack_gt* stack_gt;
Если ничего другого, я пойду с typedef struct _stack_gt* stack_gt;
Проблема в том, что здесь:
typedef struct stack_gt* stack_gt;
вы даете stack_gt
другой тип, хотя это работает нормально:
typedef struct stack_gt* stack_gtB;
clang
дает нам более приятное сообщение об ошибке:
ошибка: переопределение typedef с разными типами (‘struct stack_gt *’ vs ‘stack_gt’)
Это описано в разделе проекта стандарта C ++. 7.1.3
Спецификатор typedef параграф 6:
В данной области видимости спецификатор typedef не должен использоваться для переопределения имени любого типа, объявленного в этой области для ссылки на другой тип. [ Пример:
class complex { / ... / };
typedef int complex; // error: redefinition
— конец примера]
Хотя использовать то же имя хорошо, так что все будет в порядке:
typedef struct stack_gt stack_gt;
охвачено в пункте 3:
В данной области, не относящейся к классу, спецификатор typedef может использоваться для переопределения имени любого типа, объявленного в этой области, для ссылки на тип, к которому он уже относится. [ Пример:
typedef struct s { / ... / } s;
typedef int I;
typedef int I;
typedef I I;
— конец примера]
Еще одна идея:
#ifdef __cplusplus
extern "C" {
typedef void * stack_gt
#else
typedef struct stack_gt* stack_gt;
#endif
Это уродливо, но вам не нужно переписывать любую другую часть кода, только этот заголовок включен в C++
, Он используется только как непрозрачный указатель в C++
в любом случае, и C
не замечает