title: Generic Function Macros and How to Suppress Specific GCC Warning: "Pointer Type Mismatch in Conditional Expression"
body: <p>Before someone instantly marks this as a duplicate, let me say that I have spent a few hours searching for an answer to this (and read many similar S/O questions)</p>
  
  <p>Here's the situation: I'm playing around with <code>_Generic</code> and trying to implement a dictionary structure which auto-casts upon retrieval. Let me explain (<em>if you don't care, skip ahead to the bold header</em>). From what I see, the go-to way to have a dictionary structure in which all values belong to the same field involves <code>void</code> pointers, which require the user to cast upon retrieval; here is an example:</p>
  
  <pre class="lang-c prettyprint-override"><code>struct C99_Dict *d = new_C99_Dict(); /* Creates a pointer to an empty dict
                                          d: {} */
  int i = 7;
  put_in_c99_dict(d,"key",i); /* d: {"key": (void *)&amp;i} */
  ...
  // BAD: Will cast to i's address
  int j = get_from_c99_dict(d,"key");
  // BAD: Dereferencing void pointer
  int k = *(get_from_c99_dict(d,"key"));
  // GOOD: Will set l equal to 7
  int l = *(int *)get_from_c99_dict(d,"key");
  </code></pre>
  
  <p>As one might imagine, after a while (especially once <code>struct *</code>s get thrown into the mix...although that's unchanged in my current project) your code ends up looking like something out of a Lisp textbook.</p>
  
  <p>Using <code>_Generic</code>, however, I have managed to figure out a way to make an easier-to-use dictionary which auto-casts in such a fashion that the line</p>
  
  <pre class="lang-c prettyprint-override"><code>int j = get_from_c11_dict(d,"key");
  </code></pre>
  
  <p>becomes perfectly valid and works as one would expect (for builtins...structs still require manual casting). Changing the behavior of <code>put_in_c11_dict</code> based on the input type is easy enough, for the <code>_Generic</code> keyword does all of the heavy lifting. What is difficuly, however, is the notion of casting on the way <em>out</em>. This is because, in order for the dictionary <code>struct</code> to be well-defined, its value must be a consistent type (e.g. <code>void*</code>, as I have implemented). The problem with this, however, is that the type information is lost after the insertion function has processed the given input.</p>
  
  <p>My initial (failed) attempt at a workaround for this was to make a dictionary struct of the following form:</p>
  
  <pre class="lang-c prettyprint-override"><code>typedef struct _dict_mem_struct{
    union {
      _Bool(*bool_get)(_dict_mem_struct*);
      char(*char_get)(_dict_mem_struct*);
      ...
      char *(*char_point_get)(_dict_mem_struct*);
      void *(*void_point_get)(_dict_mem_struct*);
    } get;
    void *value;
  } _dict_mem_t;
  </code></pre>
  
  <p>In hopes of (albeit perhaps foolishly so) being able to do the following in a <code>_get</code> helper macro definition:</p>
  
  <pre class="lang-c prettyprint-override"><code>#define _get(mem_struct) _Generic((mem_struct.get) ... )
  </code></pre>
  
  <p>Unfortunately, I then learned from gdb that <code>mem_struct.get</code> was of type <code>union</code>, so it was back to the drawing board. Eventually, I got something that worked. First, I added a <code>char*</code> field to the member structure which contained the original type. Then what I really needed was an inlined switch statement, since I had no prior indication of what the function signature would be. So, here's the hideous thing I did (is it technically invalid C? Maybe. Probably. I don't know. Nevertheless, GCC compiles it and it works, so I'm happy.)</p>
  
  <pre class="lang-c prettyprint-override"><code>#define IS_PFX(val,pfx) (!strcmp(val-&gt;pfx, pfx))
  #define _get(valstruct) (IS_PFX(valstruct,"bool") ? boolval(valstruct) : IS_PFX(valstruct,"char") ? charval(valstruct) : ... : valstruct)
  </code></pre>
  
  <p>Yeah, I know; I'm probably going to hell for this. So, with that...</p>
  
  <p><strong>Here's my actual problem:</strong> When I compile this, it works, but gcc gets extremely upset with me. It gives me a bunch of errors such as</p>
  
  <pre><code>dict.c:203:75: warning: pointer type mismatch in conditional expression
   #define PAIR(valstruct,str,fn,rst) (IS_PFX(valstruct,str) ? fn(valstruct) : rst)
  </code></pre>
  
  <p>From what I can gather, this means gcc is upset that these functions are all of different types. Nevertheless, as previously stated, the code <em>works</em>, so I would like to tell gcc to put a sock in it for specifically those warnings. The problem is that when I run <code>gcc -fdiagnostics-show-option</code>, those warning lines have no <code>-W...</code> flag after them. Furthermore, I have read through the gcc warning flag page, and nothing stands out as obvious to me which I could use to suppress these. Finally, the warnings still do not go away after adding the lines <code>#pragma GCC diagnostic ignored "-Wall"</code> and <code>#pragma GCC diagnostic ignored "-Wextra"</code>. How can I get rid of these? Another solution I would be fine with is somehow turning off all warnings for specifically that file, since the reason I don't want them is so that I can integrate this into other projects without headache.</p>
  
  <p>Thanks for any and all assistance. By the way, if there is some better way to do all of this, then <em>please</em> let me know. Regardless, I'm thinking I'll make a git repo for this once I've worked some of these kinks out, since I think it would be useful (if so, I'll update this post with a link).</p>