0

For the code :

static const char *a = NULL;
abc((char **)&a);

abc method is defined as :

abc(char** a)

I get error (warning treated as error) as :

  error: cast discards '__attribute__((const))' qualifier from pointer target type [-Werror=cast-qual]

To fix this , i added :

#ifdef _PTR_CAST_
#define SIZE_T_CAST uintptr_t 
#else
#define SIZE_T_CAST size_t
#endif

My problem is , should the api call be

abc( (char **)(SIZE_T_CAST)&a); or
abc( (char **)(SIZE_T_CAST *)&a);

It doesnot complain for both , but what is the correct way ?

CodeTry
  • 312
  • 1
  • 19
  • First of all, can you please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) and show us? And then also tell us *where* you get the error? As e.g. a comment in the code? – Some programmer dude May 31 '17 at 08:50
  • I have all the code possible for this problem which makes it quite complete and self-explanatory. – CodeTry May 31 '17 at 08:55
  • Well, then... So now you have to tell us if you're programming in C or C++? The two languages are *very* different even if they sometimes look the same. My guess is that you're programming in C++, and in that case all you need is a [`const_cast`](http://en.cppreference.com/w/cpp/language/const_cast). – Some programmer dude May 31 '17 at 08:57
  • Sorry for that , i am using C. I got suggestion as C++ and i added it. Have removed it now. – CodeTry May 31 '17 at 08:59
  • Then I don't really see how you would get that warning? `&a` is a `const char **` which you cast to `char **` which is all fine in C. You *do* get the error on the `abc` call line? Not somewhere else? – Some programmer dude May 31 '17 at 09:01
  • @Someprogrammerdude they're using a compile switch to warn about this cast even though it's legal code (the theory being that this sort of coding practice can lead to silent UB) – M.M May 31 '17 at 09:02
  • Both of those casts are *wrong* IMO. You already have the correct one, but decided to tell the compiler it's not. If you do this on many places then I would say the warning was added without due consideration, otherwise if it's only one or a few places then disable the warning for those calls using pragmas. – Some programmer dude May 31 '17 at 09:10

1 Answers1

1

Firstly, the macro SIZE_T_CAST is a poor idea. Just use the right type in the first place.

The codes (char **)(uintptr_t)&a and (char **)(void *)&a are likely to work , although not guaranteed by the C Standard.

However it would be much better coding style to not use the cast. Instead make a wrapper function, e.g. in the header file you could have:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-qual"
inline void const_abc(const char ** p)
{
    abc( (char **)p );
}
#pragma GCC diagnostic pop

and then in the rest of the code, call const_abc when you have a const char ** argument.

See here for more info about disabling the warning for particular parts of the code.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • Could you please help me understand how would (char **)(uintptr_t)&a and (char **)(uintptr_t *)&a be different in the above case ? The compiler doesnot complain about both, it compiles without any warning. – CodeTry May 31 '17 at 09:15
  • 1
    @CodeTry `a` might not be correctly aligned for `uintptr_t`, and in both cases the standard doesn't guarantee that a series of casts like this produces the intended result (the only guarantee is a round trip cast back to exactly the same type). If you don't get a warning for your second suggestion, try using `void *` instead of `uintptr_t *` (it doesn't make much sense to use `uintptr_t *` anyway) – M.M May 31 '17 at 09:17
  • Actually yes, void * should work. Thanks a lot for your time. – CodeTry May 31 '17 at 09:27