Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I've reviewed the information in these posts:</p> <p><a href="https://stackoverflow.com/questions/17619015/why-one-should-not-hide-a-structure-implementation-that-way">Why one should not hide a structure implementation that way?</a></p> <p><a href="https://stackoverflow.com/questions/4440476/static-allocation-of-opaque-data-types">Static allocation of opaque data types</a></p> <p>as well as the comments. I think I have an answer that works: I switched to using an opaque pointer type but am now exposing a function call which tells the user how large it is so that he can call alloca or malloc or whatever in order to allocate the space. Basically the requirement is that allocation is performed by the user, not to the implementation.</p> <p>Modified header:</p> <pre><code>#pragma once #include &lt;inttypes.h&gt; struct Foo; typedef struct Foo Foo; void Foo_init(Foo *f); void Foo_set_bar(Foo *f, int barval); int Foo_get_bar(Foo *f); size_t Foo_data_size(void); #define Foo_alloca() alloca(Foo_data_size()) #define Foo_new() malloc(Foo_data_size()) #define Foo_delete(PTR) do { \ free(PTR); \ PTR = NULL; \ } while(0) </code></pre> <p>Modified implementation definition:</p> <pre><code>typedef int64_t bar_t; struct Foo { volatile bar_t bar; }; void Foo_init(struct Foo *foo) { struct Foo foodata; foodata.bar = (bar_t)0; memcpy(foo, &amp;foodata, Foo_data_size()); } size_t Foo_data_size() { return sizeof(struct Foo); } //... </code></pre> <p>Then in the user code, use alloca with the size provided by Foo_data_size() or use a convenience macro.</p> <p>This approach removes the fixed-size limitation and hopefully addresses the alignment issues mentioned.</p> <p>Unrelated is the word volatile in the private struct declaration. Without declaring it this way, gcc at least on win32 tried to optimize away my constraint checks on storing certain values in incompatible representations.</p> <p>Example usage:</p> <pre><code>#include "foo.h" //... { Foo *foo = Foo_alloca(); Foo_init(foo); Foo_set_bar(foo, INT_MAX); int bar = Foo_get_bar(foo); printf("Got bar: %d\n", bar); } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload