Thomas
Thomas

Reputation: 3381

Implicit parameter cast

I have a C code that works in the following way: the header contains a declaration for the function, say:

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

void foo(MyStruct* bar);

And then, in my .c code, I have this:

typedef struct EXTENDED
{
    float more_stuff;
} EXTENDED;

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

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

This compiles fine under MSVC (with warnings telling me that the header and implementation parameters don't match) but Code::Blocks (GCC) throws an error on it. Is there a way to silence this error or at least make it a warning, or is my only option to put the extra definitions in the header as well?

I'm doing this because I'm coding a modular library in C, so sometimes the individual components require "scratch space" to work (which is the void* reserved in the header), and to avoid having a bunch of casts everywhere I'm trying to implicitly cast the general-purpose MyStruct structure to a more specialized one.

So my question is, which option should I use to change this sort of error into a warning, and/or is there a better way to achieve this? (I am required to use standard C).

Upvotes: 0

Views: 450

Answers (2)

Keith Thompson
Keith Thompson

Reputation: 263267

There is no implicit conversion between MyStruct* and MyStructEx*.

(A terminology quibble: there's no such thing as an "implicit cast". A cast is an explicit conversion, using the cast operator, which consists of a parenthesized type name.)

There's also no guarantee that void* and EXTENDED* have the same size and representation; it would be perfectly legal, for example, for void* to be 8 bytes and EXTENDED* to be 4 bytes.

Any technique that assumes MyStruct and MyStructEx have the same layout is going to cause your program's behavior to be undefined.

It seems like the foo function that takes a MyStruct* and the foo function that takes a MyStructEx* need to be two different functions, with two different names. One of them can be a wrapper for the other.

Either that, or you could drop the MyStructEx type and use MyStruct for everything, with foo() doing any necessary conversions.

Upvotes: 1

Johannes Schaub - litb
Johannes Schaub - litb

Reputation: 507005

Keep the function prototype and cast the pointer in the function definition

typedef struct EXTENDED
{
    float more_stuff;
} EXTENDED;

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

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

It will shut the compiler.

Upvotes: 3

Related Questions