On 16.08.2016 19:55, Andrea Bolognani wrote:
On Tue, 2016-08-16 at 18:49 +0200, Michal Privoznik wrote:
> On 16.08.2016 13:40, Andrea Bolognani wrote:
>>
>> The first argument should be const char ** instead of
>> char **, because this is a search function and as such it
>> doesn't, and shouldn't, alter the haystack in any way.
>>
>> This change means we no longer have to cast arrays of
>> immutable strings to arrays of mutable strings; we still
>> have to do the opposite, though, but that's reasonable.
>
> Is it? I mean, we are restricting ourselves and compiler fails to see
> that. To me 'const char **' is more restrictive than 'char **'
therefore
> there should be no typecast required. But this is the discussion I
> should have with gcc devels. For some reason, gcc does automatic
> typecasting to const just for the fist level pointers and not the second
> one. That's why compilers errors out.
The reason for this behavior is explained in the C FAQ:
http://c-faq.com/ansi/constmismatch.html
This is very controversial to me. They argue that compiler cannot hold
up to your promise with the following code:
const char c = 'x'; /* 1 */
char *p1; /* 2 */
const char **p2 = &p1; /* 3 */
*p2 = &c; /* 4 */
*p1 = 'X'; /* 5 */
What they are arguing there is that step 3 shouldn't be allowed, because
the compiler cannot hold up to our promise about constness of p2. Well I
disagree. p2 is const char ** which means that only the first level
pointer is const, the second level is pure char *. Therefore in my eyes
it's step 4 where the problem is and where compiler should warn me. I
mean, after I've dereferenced p2, I'm left with 'char *' which I'm
trying to assign address of a const char. IOW:
char * var1 = (const char *) var2;
Obviously, this is not allowed. And compiler has to know what 'const
char **' means, just like what 'char *' means. So I don't really
understand their reasoning there.
Michal