0

我有一个按以下方式工作的 C 代码:标头包含函数的声明,例如:

typedef struct MyStruct
{
    int thing;
    void* reserved;
} MyStruct;

void foo(MyStruct* bar);

然后,在我的 .c 代码中,我有这个:

typedef struct EXTENDED
{
    float more_stuff;
} EXTENDED;

struct MyStructEx
{
    int thing;
    EXTENDED* ex;
} MyStructEx;

void foo(MyStructEx* bar)
{
    ...
}

这在 MSVC 下编译得很好(警告告诉我标头和实现参数不匹配)但是 Code::Blocks (GCC) 会引发错误。有没有办法消除这个错误或至少让它成为一个警告,或者我唯一的选择是把额外的定义也放在标题中?

我这样做是因为我正在用 C 编写一个模块化库,所以有时各个组件需要“临时空间”才能工作(这是标题中保留的 void*),并避免在任何地方都有一堆演员表'正在尝试将通用的 MyStruct 结构隐式转换为更专业的结构。

所以我的问题是,我应该使用哪个选项将此类错误更改为警告,和/或是否有更好的方法来实现这一点?(我需要使用标准 C)。

4

2 回答 2

3

保留函数原型并在函数定义中强制转换指针

typedef struct EXTENDED
{
    float more_stuff;
} EXTENDED;

struct MyStructEx
{
    int thing;
    EXTENDED* ex;
} MyStructEx;

void foo(MyStruct* bar)
{
    MyStructEx *mse = (MyStructEx*)bar;
    ...
}

它将关闭编译器。

于 2012-07-11T22:39:21.437 回答
1

MyStruct*和之间没有隐式转换MyStructEx*

(一个术语的狡辩:没有“隐式转换”之类的东西。转换是使用转换运算符的显式转换,它由带括号的类型名称组成。)

也不能保证void*EXTENDED*具有相同的大小和表示;这将是完全合法的,例如,为void*8 个字节和EXTENDED*4 个字节。

任何假设MyStructMyStructEx具有相同布局的技术都会导致程序的行为未定义。

似乎foo接受 a的函数MyStruct*和接受 a 的foo函数MyStructEx*需要是两个不同的函数,具有两个不同的名称。其中一个可以是另一个的包装器。

要么这样,要么您可以删除MyStructEx类型并使用MyStruct所有内容,并foo()进行任何必要的转换。

于 2012-07-11T22:44:40.827 回答