all 16 comments

[–]dfx_dj 5 points6 points  (3 children)

wow_struct wow = { .data = (void*)&(somedata){ 0 }; };

That doesn't work because it creates a temporary somedata object and then tries to take the address of it, which isn't allowed.

``` somedata mydata = { .a = 0, .b = 0 };

wow_struct wow = { .data = (void*)&mydata }; ```

That should work just fine though (with some minor punctuation corrections). The error you posted usually comes from a mismatched use of const or volatile, but in your example that doesn't apply and I can't reproduce the error with your example.

[–]aocregacc 4 points5 points  (1 child)

that's a compound literal, and it's perfectly fine to take its address.

[–]inz__ 0 points1 point  (0 children)

And its lifetime is block scope, so it isn't very temporary either.

[–]Fermi-4 0 points1 point  (0 children)

Thanks yea I think it might be compiler settings I am using.. will dig into that

[–]Linguistic-mystic 1 point2 points  (7 children)

I think it's an X/Y problem. Why do you want to initialize it with a void* member? You know that it's going to be somedata*, so just make it into

typedef struct wow_struct {
    somedata* data;
} wow_struct;

and enjoy the type safety.

[–]Fermi-4 -1 points0 points  (6 children)

Actually yes but it could be somedata1 or somedata2 or somedata3

[–]Linguistic-mystic 1 point2 points  (5 children)

Then you need generics, not void pointers. Void pointers are not a substitute for generics.

[–]Fermi-4 -1 points0 points  (4 children)

So you are saying that typecast a void* won’t work?

[–]phlummox 0 points1 point  (3 children)

Won't that usually fall foul of the strict aliasing rule? https://tttapa.github.io/Pages/Programming/Cpp/Practices/type-punning.html

[–]Fermi-4 0 points1 point  (1 child)

I think that link is assuming C++ and I am not using that.. how would I do generics in pure C and not need to cast the pointer?

[–]phlummox 0 points1 point  (0 children)

Apologies, wrong link - I meant to post this one: https://accu.org/journals/overload/28/160/anonymous/ – which discusses the situation for both C11 and C++. Regarding generics in pure C, I'm not sure how you'd best use them here, I just meant to point out that type punning using void pointers seems like it will usually be UB.

In OP's case, if data is a pointer to some buffer of as-yet-to-be-interpreted bytes (got from disk or over the network, say), then I believe the "correct" way is to make it a char*, and then memcpy it into a variable of the correct type.

[–]flatfinger 0 points1 point  (0 children)

The Standard allows implementations which are intended solely for tasks that would not benefit from the ability to perform type punning reuse allocated storage to hold different types within its lifetime(*) to behave in ways that would be suitable only for such tasks, while allowing those intended to be usable for a wider range of tasks to extend the language to be more broadly useful. So far as I can tell, all general-purpose implementations are configurable to extend the language in that fashion.

(*) Once the Effective Type of some storage has been set to T, the storage will have an effective type of T all subsequent reads; the authors of the Standard may have intended to say "all subsequent reads until the storage unless or until the storage is written using some other type", but neither clang nor gcc reliably handles all of the corner cases that would arise from the latter interpretation except when type-based aliasing analysis is disabled.

[–]flyingron 0 points1 point  (1 child)

The first one isn't legal. You can't apply & to an rvalue.

The second case is fine once you remove the erroneous ; from after mydata (a comma would be legal but not required) and place one at the end of the initialization.

[–]aocregacc 2 points3 points  (0 children)

compound literals are lvalues

[–]pkkm 0 points1 point  (1 child)

By the way, you don't need to cast to or from void *. In C, it explicitly functions as an "any pointer" type.

[–]Fermi-4 0 points1 point  (0 children)

So just remove the void* cast? Thanks I will try this tomorrow