2

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::的第 8 行typedef struct stack_gt* stack_gt;

编辑 2

如果没有别的,我会去typedef struct _stack_gt* stack_gt;

4

2 回答 2

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;

—结束示例]

于 2014-03-30T02:30:21.683 回答
1

另一个想法:

 #ifdef __cplusplus

 extern "C" {
 typedef void * stack_gt

 #else

 typedef struct stack_gt* stack_gt;

 #endif

这很难看,但您不需要重写代码的任何其他部分,只需将这个头文件包含在C++. C++无论如何,它仅用作不透明的指针,并且C不会注意到。

于 2014-03-30T03:51:16.187 回答