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如何在不更改代码中的任何内容的情况下编译程序?
stackg.h
:: typedef struct stack_gt* stack_gt;
如果不出意外,我会选择typedef struct _stack_gt* stack_gt;
答案 0 :(得分: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
-end example]
虽然使用相同的名称很好,但这样就可以了:
typedef struct stack_gt stack_gt;
3 段中的
在给定的非类作用域中,可以使用typedef说明符重新定义该作用域中声明的任何类型的名称,以引用它已引用的类型。 [例如:
typedef struct s { / ... / } s;
typedef int I;
typedef int I;
typedef I I;
-end example]
答案 1 :(得分:1)
另一个想法:
#ifdef __cplusplus
extern "C" {
typedef void * stack_gt
#else
typedef struct stack_gt* stack_gt;
#endif
这很难看,但您不需要重写代码的任何其他部分,只有C++
中包含此标头。它仅在C++
中用作不透明指针,而C
并未注意到。