Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Is char** (or char*[]) implicitly convertible to 'const char * const *'?

Reply
Thread Tools

Is char** (or char*[]) implicitly convertible to 'const char * const *'?

 
 
Greg Comeau
Guest
Posts: n/a
 
      10-29-2005
In article <(E-Mail Removed)>,
Jordan Abel <(E-Mail Removed)> wrote:
>On 2005-10-29, Greg Comeau <(E-Mail Removed)> wrote:
>> In article <(E-Mail Removed)>,
>> Jordan Abel <(E-Mail Removed)> wrote:
>>>On 2005-10-29, http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote:
>>>> Greg,
>>>>
>>>> I understand why 'char**' is not convertible to 'const char**'. Here's
>>>> why "char**" is not convertible to "const char**". Here's how I
>>>> explain it to others. Let us see what could happen if the conversion
>>>> was allowed:
>>>>
>>>> void foo(const char** strArray)
>>>> {
>>>> strArray[0] = "Hello"; // This is OK for const char**
>>>>}
>>>
>>>Well, that's also ok for char**, since string literals are of type
>>>char * in c. The general idea still stands, though.
>>>
>>>The thing that irritates me is that despite all this, it's _trivial_
>>>to violate const in C without resorting to all this.
>>>
>>>const char foo[] = "mystring";
>>>char *constviol = strchr(foo,*foo);

>>
>> Indeed. Which is why the C++ committee plugged that hole in the
>> type system.

>
>How'd they manage that? Just out of curiosity, I know it's off-topic


C++ is OT but the underlying issues may not be per se: By plugging
as many (C) type holes as possible and/or related issues: doing
stuff like making string literals const, providing a strchr overload
(the overload itself was not the desired solution but C compatibility
was desired), requiring function prototypes, disallowing implicit int,
etc. (obviously not all these are connected to strchr()).
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
 
Reply With Quote
 
 
 
 
kevin.hall@motioneng.com
Guest
Posts: n/a
 
      10-29-2005
Greg,

Thanks for all the information! I deeply appeciate how you contribute
to the forums and help others despite being busy with your buisness.

- Kevin

 
Reply With Quote
 
 
 
 
Netocrat
Guest
Posts: n/a
 
      10-29-2005
On Sat, 29 Oct 2005 16:49:54 -0400, Greg Comeau wrote:
> In article <(E-Mail Removed)>, Jordan Abel
> <(E-Mail Removed)> wrote:
>>On 2005-10-28, Skarmander <(E-Mail Removed)> wrote:
>>> ...
>>> The answer is no, these implicit conversions are not allowed. An
>>> explicit cast is required. From the FAQ:
>>> http://www.eskimo.com/~scs/C-faq/q11.10.html.

>>
>>I'd like to know the justification for this. Is there or might there be
>>a system on which const pointers have a different representation than
>>non-const ones?


N869, 6.2.5, para 26
The qualified or unqualified versions of a [pointer type] ... have the
same representation and alignment requirements.

and para 27:
[P]ointers to qualified or unqualified versions of compatible types
shall have the same representation and alignment requirements.

>>You (and that FAQ) seem to think that a cast would work, and would not
>>cause undefined behavior,


The FAQ should IMO be clarified here. It _could_ cause undefined
behaviour if (as described elsethread and in Greg's FAQ) such a cast were
used to violate const-protection.

>> which makes me think that the constraint is
>>entirely spurious, and only exists to force people to type needless
>>casts.


It's a violation of const-safety to be able to implicitly convert char **
to const char **, but the prohibition of other implicit conversions (e.g.
char ** to const char *const *) does seem to be spurious.

When this objection has come up in the past, the explanation has been that
the standard's authors were being cautious with a new rule (and Greg has
again cited this explanation in the current thread).

>>If there's a legitimate case for not allowing it to implicitly convert,
>>then a cast, too, would cause undefined behavior (like trying to cast
>>int ** to void **)

>
> AFAIRecall, you are correct: the cast is not required to make it work
> and hence it's not a case of "would work" but _could_ work.


The cast itself is required to work though. By N869, 6.5, para 7 the
aliasing rules allow a const pointer to be accessed through a compatible
non-const lvalue (and vice-versa), and 6.3.2.3. para 2 states:

For any qualifier q, a pointer to a non-q-qualified type may be
converted to a pointer to the q-qualified version of the type; the
values stored in the original and converted pointers shall compare
equal.

--
http://members.dodo.com.au/~netocrat
 
Reply With Quote
 
Greg Comeau
Guest
Posts: n/a
 
      10-30-2005
In article <(E-Mail Removed)>,
Netocrat <(E-Mail Removed)> wrote:
>On Sat, 29 Oct 2005 16:49:54 -0400, Greg Comeau wrote:
>> In article <(E-Mail Removed)>, Jordan Abel
>> <(E-Mail Removed)> wrote:
>>>If there's a legitimate case for not allowing it to implicitly convert,
>>>then a cast, too, would cause undefined behavior (like trying to cast
>>>int ** to void **)

>>
>> AFAIRecall, you are correct: the cast is not required to make it work
>> and hence it's not a case of "would work" but _could_ work.

>
>The cast itself is required to work though. By N869, 6.5, para 7 the
>aliasing rules allow a const pointer to be accessed through a compatible
>non-const lvalue (and vice-versa), and 6.3.2.3. para 2 states:
>
> For any qualifier q, a pointer to a non-q-qualified type may be
> converted to a pointer to the q-qualified version of the type; the
> values stored in the original and converted pointers shall compare
> equal.


We may be talking about two different things, but from C99 6.7.3p5
(also C90 3.5.3p4):

"If an attempt is made to modify an object defined with a
const-qualified type through use of an lvalue with
non-const-qualified type, the behavior is undefined."

Casting does not excuse this. If this is what you're saying,
then we agree. I'm talking about the case where in the
example the underlying char is const, not the case where it isn't.
--
Greg Comeau / Celebrating 20 years of Comeauity!
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
 
Reply With Quote
 
Netocrat
Guest
Posts: n/a
 
      10-30-2005
On Sat, 29 Oct 2005 20:36:02 -0400, Greg Comeau wrote:
> In article <(E-Mail Removed)>,
> Netocrat <(E-Mail Removed)> wrote:
>>On Sat, 29 Oct 2005 16:49:54 -0400, Greg Comeau wrote:
>>> In article <(E-Mail Removed)>, Jordan Abel
>>> <(E-Mail Removed)> wrote:
>>>>If there's a legitimate case for not allowing it to implicitly convert,
>>>>then a cast, too, would cause undefined behavior (like trying to cast
>>>>int ** to void **)
>>>
>>> AFAIRecall, you are correct: the cast is not required to make it work
>>> and hence it's not a case of "would work" but _could_ work.

>>
>>The cast itself is required to work though. By N869, 6.5, para 7 the
>>aliasing rules allow a const pointer to be accessed through a compatible
>>non-const lvalue (and vice-versa), and 6.3.2.3. para 2 states:
>>
>> For any qualifier q, a pointer to a non-q-qualified type may be
>> converted to a pointer to the q-qualified version of the type; the
>> values stored in the original and converted pointers shall compare
>> equal.

>
> We may be talking about two different things, but from C99 6.7.3p5


Yes, my comment was a slight side-track (that's why I prefaced it with
"The cast itself); I wasn't intending to negate what you said.

> (also C90 3.5.3p4):
>
> "If an attempt is made to modify an object defined with a
> const-qualified type through use of an lvalue with
> non-const-qualified type, the behavior is undefined."
>
> Casting does not excuse this. If this is what you're saying,
> then we agree.


We agree. I was simply saying that the cast itself (and access to the
cast pointer) does not invoke undefined behaviour - it's access to what
the pointer points to that (potentially) invokes undefined behaviour.

> I'm talking about the case where in the
> example the underlying char is const, not the case where it isn't.


--
http://members.dodo.com.au/~netocrat
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
(const char *cp) and (char *p) are consistent type, (const char **cpp) and (char **pp) are not consistent lovecreatesbeauty C Programming 1 05-09-2006 08:01 AM
Is char*[] convertible to const char*[]? kevin.hall@motioneng.com C Programming 10 09-05-2005 06:06 AM
extern const char * vs. extern const char []http://tinyurl.com/47e3k Thomas Matthews C++ 5 08-02-2004 10:36 AM
Exact difference between 'const char *' and 'char *', also diff between 'const' and 'static' Santa C Programming 1 07-17-2003 02:10 PM



Advertisments