Generic Function Macros and How to Suppress Specific GCC Warning: "Pointer Type Mismatch in Conditional Expression"

belph

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)

Here's the situation: I'm playing around with _Generic and trying to implement a dictionary structure which auto-casts upon retrieval. Let me explain (if you don't care, skip ahead to the bold header). From what I see, the go-to way to have a dictionary structure in which all values belong to the same field involves void pointers, which require the user to cast upon retrieval; here is an example:

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 *)&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");

As one might imagine, after a while (especially once struct *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.

Using _Generic, 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

int j = get_from_c11_dict(d,"key");

becomes perfectly valid and works as one would expect (for builtins...structs still require manual casting). Changing the behavior of put_in_c11_dict based on the input type is easy enough, for the _Generic keyword does all of the heavy lifting. What is difficuly, however, is the notion of casting on the way out. This is because, in order for the dictionary struct to be well-defined, its value must be a consistent type (e.g. void*, 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.

My initial (failed) attempt at a workaround for this was to make a dictionary struct of the following form:

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;

In hopes of (albeit perhaps foolishly so) being able to do the following in a _get helper macro definition:

#define _get(mem_struct) _Generic((mem_struct.get) ... )

Unfortunately, I then learned from gdb that mem_struct.get was of type union, so it was back to the drawing board. Eventually, I got something that worked. First, I added a char* 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.)

#define IS_PFX(val,pfx) (!strcmp(val->pfx, pfx))
#define _get(valstruct) (IS_PFX(valstruct,"bool") ? boolval(valstruct) : IS_PFX(valstruct,"char") ? charval(valstruct) : ... : valstruct)

Yeah, I know; I'm probably going to hell for this. So, with that...

Here's my actual problem: When I compile this, it works, but gcc gets extremely upset with me. It gives me a bunch of errors such as

dict.c:203:75: warning: pointer type mismatch in conditional expression
 #define PAIR(valstruct,str,fn,rst) (IS_PFX(valstruct,str) ? fn(valstruct) : rst)

From what I can gather, this means gcc is upset that these functions are all of different types. Nevertheless, as previously stated, the code works, so I would like to tell gcc to put a sock in it for specifically those warnings. The problem is that when I run gcc -fdiagnostics-show-option, those warning lines have no -W... 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 #pragma GCC diagnostic ignored "-Wall" and #pragma GCC diagnostic ignored "-Wextra". 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.

Thanks for any and all assistance. By the way, if there is some better way to do all of this, then please 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).

Jens Gustedt

gcc is probably right, you are mixing different pointer types in a ternary expression. So your design is most probably wrong. Have in mind that _Generic can't do miracles, the type system in C remains static, determined at compile time. It can only take care of type information that you pass to it in the first expression.

If you cast away type information to void*, store the pointer somewhere and try to retrieve it later, by definition _Generic can't help you. The context of the retrieval doesn't have the type information anymore, it might be called for such pointers that come from different places.

So in particular for a dictionary structure C can never know at the retrieval side, what type the original pointer had been. If you want to keep that information, you'd have to do that yourself and store that information along with the pointer.

BTW, already your question title is wrong: there is no such thing as a generic function in C. There are type generic function-like macros.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Generic Function Macros and How to Suppress Specific GCC Warning: "Pointer Type Mismatch in Conditional Expression"

From Dev

How to suppress a specific warning in Swift

From Dev

How to suppress "function is never used" warning for a function used by tests?

From Dev

How to suppress a specific warning sent by cron daemon to email?

From Dev

Suppress specific MySQL warning message

From Dev

How to suppress MaxPermSize warning?

From Dev

How to suppress Scalastyle warning?

From Dev

How to suppress matplotlib warning?

From Dev

xcode 7 how to suppress warning "overrides a member function but is not marked 'override'"

From Dev

Can't suppress GCC -Wextra warning

From Dev

How to suppress GCC variadic macro argument warning for zero arguments for a particular macro definition within a source file

From Dev

How to suppress "warning: missing initializer" caused by Boost.Log and GCC 4.4?

From Dev

Java: Generic type casting, how can I fix this so I don't suppress the unchecked warning

From Java

How to call a function on an object with a generic type parameter using scala macros?

From Dev

Suppress warning for function arguments not used in LISP

From Dev

gcc suppress warning "too small to hold all values of"

From Dev

gcc: How to avoid "used but never defined" warning for function defined in assembly

From Dev

How to specialize a call to generic function with specific derrivation of that generic in Java?

From Dev

How to suppress unchecked typecast warning with generics not at declaration?

From Dev

How to suppress a 'missing termination character' warning in cpp?

From Dev

How to suppress "Can be replaced with foreach call" warning

From Dev

How to suppress Android Lint warning in Gradle script

From Dev

How to suppress deprecation warning on annotation argument

From Dev

How to suppress compiler warning C4373

From Dev

How to suppress warning messages when loading a library?

From Dev

How to suppress a "SpriteKit Texture Atlas Generator Warning"?

From Dev

How to suppress "possible unintended reference comparison" warning?

From Dev

How to suppress hash after insertion warning?

From Dev

How to suppress a 'missing termination character' warning in cpp?

Related Related

  1. 1

    Generic Function Macros and How to Suppress Specific GCC Warning: "Pointer Type Mismatch in Conditional Expression"

  2. 2

    How to suppress a specific warning in Swift

  3. 3

    How to suppress "function is never used" warning for a function used by tests?

  4. 4

    How to suppress a specific warning sent by cron daemon to email?

  5. 5

    Suppress specific MySQL warning message

  6. 6

    How to suppress MaxPermSize warning?

  7. 7

    How to suppress Scalastyle warning?

  8. 8

    How to suppress matplotlib warning?

  9. 9

    xcode 7 how to suppress warning "overrides a member function but is not marked 'override'"

  10. 10

    Can't suppress GCC -Wextra warning

  11. 11

    How to suppress GCC variadic macro argument warning for zero arguments for a particular macro definition within a source file

  12. 12

    How to suppress "warning: missing initializer" caused by Boost.Log and GCC 4.4?

  13. 13

    Java: Generic type casting, how can I fix this so I don't suppress the unchecked warning

  14. 14

    How to call a function on an object with a generic type parameter using scala macros?

  15. 15

    Suppress warning for function arguments not used in LISP

  16. 16

    gcc suppress warning "too small to hold all values of"

  17. 17

    gcc: How to avoid "used but never defined" warning for function defined in assembly

  18. 18

    How to specialize a call to generic function with specific derrivation of that generic in Java?

  19. 19

    How to suppress unchecked typecast warning with generics not at declaration?

  20. 20

    How to suppress a 'missing termination character' warning in cpp?

  21. 21

    How to suppress "Can be replaced with foreach call" warning

  22. 22

    How to suppress Android Lint warning in Gradle script

  23. 23

    How to suppress deprecation warning on annotation argument

  24. 24

    How to suppress compiler warning C4373

  25. 25

    How to suppress warning messages when loading a library?

  26. 26

    How to suppress a "SpriteKit Texture Atlas Generator Warning"?

  27. 27

    How to suppress "possible unintended reference comparison" warning?

  28. 28

    How to suppress hash after insertion warning?

  29. 29

    How to suppress a 'missing termination character' warning in cpp?

HotTag

Archive