Непрозрачный указатель в MSVC генерирует ошибку компилятора

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;

Редактировать 2

Если ничего другого, я пойду с typedef struct _stack_gt* stack_gt;

2

Решение

Проблема в том, что здесь:

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;

— конец примера]

2

Другие решения

Еще одна идея:

 #ifdef __cplusplus

extern "C" {
typedef void * stack_gt

#else

typedef struct stack_gt* stack_gt;

#endif

Это уродливо, но вам не нужно переписывать любую другую часть кода, только этот заголовок включен в C++ , Он используется только как непрозрачный указатель в C++ в любом случае, и C не замечает

1

По вопросам рекламы [email protected]