3
votes

I wonder if someone can advise on this issue:

I have a C11 type generic macro defined like this

#define hash_table_fetch(H,K,D) ((D *) _Generic((K), \
    int: hash_table_fetch_long, \
    long: hash_table_fetch_long, \
    char *: hash_table_fetch_str, \
    const char *: hash_table_fetch_str)(H,K))

The hash table supports both string and long keys, the parameters to the macro are the hash table, key and a datatype for a cast (the routines return void *). I can use it without problems ... mostly. The problem is that gcc generates a huge amount of code when the macro is invoked. And consequently, it cannot be used in macros that stringify its parameter, most notably assert.

For example, this works fine:

if (strcmp (hash_table_fetch (hash_table, 4, char), "four")
   printf ("BAD\n");

This, however:

assert (!strcmp (hash_table_fetch (hash_table, 4, char), "four"));

results in:

tests/hash_table_tests.c:53:2: error: string length ‘5359’ is greater than the length ‘4095’ ISO C99 compilers are required to support [-Werror=overlength-strings]
assert (!strcmp (hash_table_fetch (hash_table, 4, char), "four"));

Any workarounds? Is my macro badly written perhaps?

1

1 Answers

0
votes

Your macro looks perfectly fine, this is how _Generic is supposed to be used.

You probably only see this as an error because you have -Werror switched on. As the warning text indicates this tests for minimal conformance of your code with the constraints that are given in the C standard.

For your code this warning doesn't tell anything about portability. The string length that this complains about is self inflicted by the compiler so it will most probably something less complicated for compilers that have more resource constraints than gcc.

Switch it off.