-1

I have a function that accepts void* as parameter, but I want to use it as if it's a struct.

typedef struct struct1
{
    int val;
} struct2;

void func1(void* struct3)
{
    printf("%d",struct3->val);
}

My purpose is for example, if I have a .h file where the function is defined as

typedef void* parameter1;
void func1(parameter1 p1);

And I wants to use the struct as a parameter in that function, without declaring the struct in the .h file.

ndi equals
  • 187
  • 1
  • 9
  • 2
    Please do not use void pointers,. It usually ends up in tears – Ed Heal Jan 16 '16 at 20:39
  • 3
    you cannot use `->` on a void pointer, you need a structure pointer, or least, a cast. – Sourav Ghosh Jan 16 '16 at 20:39
  • Then how can I pass the struct as a parameter like I mentioned above without defining it in the .h file? – ndi equals Jan 16 '16 at 20:40
  • 1
    @Allen In any case within the function definition you have to know what is the actual type of the argument. – Vlad from Moscow Jan 16 '16 at 20:40
  • 2
    `printf("%d",((struct2 *)struct3)->val)`. – i486 Jan 16 '16 at 20:40
  • 1
    "without declaring the struct in the .h file". If you mean without having the definition of the struct anywhere at the point it is used then the answer is that you just can't. Either you need to include the header file or define the struct in the C file where that function is defined. – kaylum Jan 16 '16 at 20:42
  • 1
    Unless you need to pass different kind of structures to the function, and use either the first member or another argument to know which kind of structure you got, there's no need to use `void *` here. Besides that, just do it, in C all pointers can be converted to `void *` without a cast, but you need a cast to use the pointer inside the function. – Some programmer dude Jan 16 '16 at 20:43
  • 2
    Also, regarding the structure and the type-alias (`typedef`), you can have the structure name and the type alias name to be the same. Structure names lives in their own namespaces, so you can do e.g. `typedef struct foo { ... } foo;` – Some programmer dude Jan 16 '16 at 20:44

2 Answers2

1

Thanks for the answer printf("%d",((struct2 *)struct3)->val) mentioned by @i486, that's what I was looking for.

ndi equals
  • 187
  • 1
  • 9
  • Preceding a users moniker with the _address of_ operator ( _&_ ) does not work as well as the `@` symbol. Such as _@i486_. :) – ryyker Jan 16 '16 at 20:55
  • You might have been _looking_ for this, but it is very certainly not what you **need**. That is ths solution for an XY-problem and recipe for desaster. Why do you not just use the correct type for the argument? – too honest for this site Jan 16 '16 at 20:59
0

In the header, declare the structure type as an incomplete type. For example:

typedef struct struct1 struct1;
extern void func1(struct1 *p1);

Or:

struct struct1;
void func1(struct struct1 *p1);

You can mix'n'match extern or not and typedef vs struct tag.

In the implementation code (or implementation header if you have multiple source files implementing the support for the type), you include the public header and define the structure type:

struct struct1
{
    …private details…
};

In C11 and beyond, you can repeat a typedef as long as it refers to the same type; in earlier versions of C, you could not do that.

The advantage of this approach is that the client code is forced to use your functions because they don't know the internals of the structure, but they get a measure of type safety. In particular, a random structure pointer can't be passed to this function. If everything takes void *, then you can pass a wrong structure type to the function because all void pointers look alike. That's both unkind and unnecessary.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278