Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>Version 0 &mdash; Critique of Question's Code</h2> <p>The posted code does not compile.</p> <h3>api.h</h3> <pre><code>typedef void* hidden_my_type; void do_something(my_type x); </code></pre> <p>This defines <code>hidden_my_type</code> but not the <code>my_type</code> that is passed to <code>do_something()</code>. Presumably, you intended:</p> <pre><code>typedef void *my_type; void do_something(my_type x); </code></pre> <h3>core.c</h3> <pre><code>struct _my_type { int a; } </code></pre> <p>As noted below too, there is a semi-colon missing after the structure definition.</p> <pre><code>void do_something(hidden_my_type void_x) { struct *_my_type x = void_x; printf("Value: %d\n", x-&gt;a); } </code></pre> <p>You have the <code>hidden_my_type</code> vs <code>my_type</code> problem again. You have the <code>*</code> of the pointer where it cannot go; it must go after the <code>struct _my_type</code>. You probably intended something like:</p> <pre><code>void do_something(my_type void_x) { struct _my_type *x = void_x; printf("Value: %d\n", x-&gt;a); } </code></pre> <p>This is now syntactically correct (I think; I haven't actually run it past a compiler). You have not shown how it is used; indeed, since the user code has no way to generate a pointer to a valid structure, there is no way for this code to be used safely.</p> <p>Your test code (unshown &mdash; why don't you show your test code) might look something like this:</p> <pre><code>#include "api.h" int main(void) { my_type x = 0; do_something(x); return 0; } </code></pre> <p>Alternatively, it might not have the <code>= 0</code> initializer in place. Either way, your code is unable to function sanely, and a core dump is almost inevitable. When you hide the structure from the user, you have to provide them with a mechanism to get hold of a valid (pointer to) the structure, and you've not done that.</p> <h2>Version 1</h2> <p>This is a better way to do it, because it is more nearly type-safe:</p> <h3>api.h version 1</h3> <pre><code>typedef struct _my_type *my_type; void do_something(my_type x); </code></pre> <h3>core.c version 1</h3> <pre><code>#include "api.h" struct _my_type { int a; }; </code></pre> <p>Note the added semi-colon, and the include of the <code>api.h</code> file.</p> <pre><code>void do_something(my_type x) { // Now you don't have to do casting here! //struct *_my_type x = void_x; /*Don't understand is that correct way to do, as I'm getting segmentation fault error */ printf("Value: %d\n", x-&gt;a); } </code></pre> <hr> <h2>Version 2</h2> <p>Actually, we can debate the wisdom of hiding the pointer; I would prefer not to do so:</p> <h3>api.h version 2</h3> <pre><code>#ifndef API_H_INCLUDED #define API_H_INCLUDED typedef struct my_type my_type; extern void do_something(my_type *x); extern my_type *my_type_initializer(void); extern void my_type_release(my_type *x); #endif /* API_H_INCLUDED */ </code></pre> <h3>core.c version 2</h3> <pre><code>#include "api.h" #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; struct my_type { int a; }; void do_something(my_type *x) { printf("Value: %d\n", x-&gt;a); } my_type *my_type_initializer(void) { my_type *x = malloc(sizeof(*x)); x-&gt;a = 57; // More plausibly, this would be 0 return x; } void my_type_release(my_type *x) { free(x); } </code></pre> <h3>main.c</h3> <pre><code>#include "api.h" int main(void) { my_type *x = my_type_initializer(); do_something(x); my_type_release(x); return 0; } </code></pre> <p>That's nice and clean. Of course, the user cannot allocate a <code>struct my_type</code> (only a pointer to it), so you need a function to allocate the structure for them. Think of the Standard C Library, and the <code>FILE</code> type, and <code>fopen()</code> to allocate and <code>fclose()</code> to release and <code>fprintf()</code> etc to manipulate the type. The <code>my_type_initializer()</code> is functioning as an analogue to <code>fopen()</code>, <code>my_type_release()</code> as an analogue to <code>fclose()</code>, and <code>do_something()</code> as an analogue to <code>fprintf()</code>.</p>
 

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