c++gccclangqualifiersboringssl

clang, gcc, and ignored qualifiers: who is right?


I found a difference in behavior between gcc and clang when compiling BoringSSL, and was able to whittle it down to the following test case to illustrate:

typedef char *OPENSSL_STRING;
#if USE_TYPEDEF
#define constptr const OPENSSL_STRING
#else
#define constptr const char *
#endif

int
foo (const void **ap)
{
    constptr a = (constptr) *ap;
    return a != 0;
}

I tested four scenarios as follows:

sh$ g++ -c t2.cc -Wignored-qualifiers -DUSE_TYPEDEF
t2.cc: In function ‘int foo(const void**)’:
t2.cc:11:30: warning: type qualifiers ignored on cast result type [-Wignored-qualifiers]
   11 |     constptr a = (constptr) *ap;
      |                              ^~
sh$ g++ -c t2.cc -Wignored-qualifiers 
sh$ clang++ -c t2.cc -Wignored-qualifiers -DUSE_TYPEDEF
sh$ clang++ -c t2.cc -Wignored-qualifiers 
sh$ 

Is this a bug in gcc -- or is there something more going on that I don't understand?


For reference: the warning is in BoringSSL's stack.h


Solution

  • Given const OPENSSL_STRING, const is qualified on the typedef OPENSSL_STRING itself, so the type would be char * const, i.e. const pointer to non-const char (note that it's not const char *). Gcc is just trying to tell you that as the cast result the const part is ignored. i.e. (char * const) *ap; has the same effect as (char *) *ap;.

    Changing the type to int might be clearer.

    const int i = (int) 0;       // a weird conversion
    const int i = (const int) 0; // same effect as above