Topic: conversion: char** -> const char* const*


Author: pat@tesuji.qc.ca (Patrick Smith)
Date: Sat, 4 Sep 1993 04:29:28 GMT
Raw View
Some time ago, John Max Skaller asked, in relation to conversions
such as the one mentioned in the subject line,

|       How does this affect overloading?

and I responded:

|It doesn't really.
|
|It just adds more "trivial" conversions (using the terminology of
|section 13.2 of the ARM or draft standard).


But I now think that answer was wrong.

If accepted, this position would break some programs.
For example:

   void f(const char* const*);
   void f(char* const*);

   void g(char** p) { f(p); }

would be ambiguous under the above rule.  And code such as this
is actually reasonably likely to be used in current programs.
For example, the second f above might be defined as

   void f(char* const* p) { f((const char* const*) p); }

in order to circumvent the current restriction against implicit
conversions from char** to const char* const*.


The suggestion described here by David Sachs is much better:

|Andrew Koenig suggested a reasonable ranking rule, that provides a
|partial ordering analagous to the rule for mapping pointer
|(or reference) to derived class to a pointer (or reference)
|to a base class.
|
|All valid conversions formed by adding "const" or "volatile" to a
|type rank thesame EXCEPT that a conversion is poorer than another
|valid conversion with a proper subset of the added attributes.
|
|e.g. char ** -> char * const * is better than
|char ** -> const char * const *, but both conversions would rank
|equal with char ** -> char * volatile *.


--
Patrick Smith
pat@tesuji.qc.ca




Author: rfg@netcom.com (Ronald F. Guilmette)
Date: Sat, 14 Aug 1993 23:52:32 GMT
Raw View
In article <KANZE.93Aug13163234@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
>In article <hopps.745175689@mmm.com> hopps@yellow.mmm.com (Kevin J
>Hopps) writes:
>
>|> I asked my compiler supplier why I can no longer pass a (char**) to a
>|> function expecting a (const char* const*).  This was the reply:
>
>|> Alas, this isn't a bug in our compilers.  It is a 'feature' of the ANSI
>|> C Standard.  Essentially, when we wrote the rules for where const and volatile
>|> keywords can be 'tacked on' during a conversion, we only specified that you
>|> could do so to one level of pointer.  Thus, you could declare echo to accept a
>|> char *const *, but not what you've written. ...
>
>|> Is this true?
>
>Yes.  Or it was until a couple of months ago.

Correction:  The ANSI/ISO C standard HAS NOT CHANGED, however a new extension
(over and above what is allowed by ANSI/ISO C) has recently beed added to the
draft working papers of the X3J16 (ANSI/ISO C++) standardization committee.

--

-- Ronald F. Guilmette ------------------------------------------------------
------ domain address: rfg@netcom.com ---------------------------------------
------ uucp address: ...!uunet!netcom.com!rfg -------------------------------




Author: maxtal@physics.su.OZ.AU (John Max Skaller)
Date: Sun, 15 Aug 1993 01:54:42 GMT
Raw View
In article <KANZE.93Aug13163234@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
>
>The rule was introduced to prevent the security leak caused by passing
>a (char**) to a (const char**).  Regretfully, it covered too much.
>The C++ standards committee has corrected this in C++, but it will no
>doubt take a while until the correction gets into commercial compilers.

 The work is not finished :-)

 How does this affect overloading?

--
        JOHN (MAX) SKALLER,         INTERNET:maxtal@suphys.physics.su.oz.au
 Maxtal Pty Ltd,      CSERVE:10236.1703
        6 MacKay St ASHFIELD,     Mem: SA IT/9/22,SC22/WG21
        NSW 2131, AUSTRALIA




Author: ark@alice.att.com (Andrew Koenig)
Date: 15 Aug 93 05:17:38 GMT
Raw View
In article <rfgCBrwzL.Cor@netcom.com> rfg@netcom.com (Ronald F. Guilmette) writes:

> Correction:  The ANSI/ISO C standard HAS NOT CHANGED, however a new extension
> (over and above what is allowed by ANSI/ISO C) has recently beed added to the
> draft working papers of the X3J16 (ANSI/ISO C++) standardization committee.

...and it will probably be amended again at the next meeting to allow a few
additional conversions and disallow some (involving volatile) that looked
safe but aren't.

I'll post the details when I'm sure I understand the proposal; it has
theorems and stuff like that in it.
--
    --Andrew Koenig
      ark@research.att.com




Author: pat@tesuji.qc.ca (Patrick Smith)
Date: Sun, 15 Aug 1993 03:53:05 GMT
Raw View
maxtal@physics.su.OZ.AU (John Max Skaller) writes:
|In article <KANZE.93Aug13163234@slsvhdt.us-es.sel.de> kanze@us-es.sel.de (James Kanze) writes:
|>
|>The rule was introduced to prevent the security leak caused by passing
|>a (char**) to a (const char**).  Regretfully, it covered too much.
|>The C++ standards committee has corrected this in C++, but it will no
|>doubt take a while until the correction gets into commercial compilers.
|
| The work is not finished :-)
|
| How does this affect overloading?


It doesn't really.

It just adds more "trivial" conversions (using the terminology of
section 13.2 of the ARM or draft standard).

Of course, this might change the meaning of a few programs,
but there shouldn't be many affected by this change.


--
Patrick Smith
pat@tesuji.qc.ca




Author: ark@alice.att.com (Andrew Koenig)
Date: 15 Aug 93 13:19:49 GMT
Raw View
In article <CBs84I.4FH@tesuji.qc.ca> pat@tesuji.qc.ca writes:

> Of course, this might change the meaning of a few programs,
> but there shouldn't be many affected by this change.


A thoughtful and surprising comment.  I had thought that allowing
char** -> const char *const * was a compatible extension, as it would
affect only programs that used the conversion and such programs
would have been ill-formed previously.  However, after reading
the sentence above, I came up with the following:

 void f(const void*);
 void f(const char* const*);

 main()
 {
  char** p = 0;

  f(p);  // used to call f(const void*)
    // now calls f(const char* const*)
 }

Nevertheless, I think it's a good proposal.

Of course, I wrote the first version and Patrick Smith wrote the
revision, so you know where my biases lie.


--
    --Andrew Koenig
      ark@research.att.com




Author: gregc@socrates.ucsf.edu (Greg Couch %CGL)
Date: Mon, 16 Aug 1993 07:35:51 GMT
Raw View
I hope that the committee is considering multi-dimensional arrays as well:

 extern void matrix_invert(float result[4][4], float const mat[4][4]);

 int main()
 {
  float inv[4][4], a[4][4];

  matrix_invert(inv, a);  // type clash due to const
 }

This is more of a problem with ANSI C, because in C++ we would make the
matrix into a class.

 Greg Couch
 gregc@cgl.ucsf.edu




Author: b91926@fnclub.fnal.gov (David Sachs)
Date: 16 Aug 1993 19:24:07 GMT
Raw View
In article <1993Aug15.015442.27948@ucc.su.OZ.AU>, maxtal@physics.su.OZ.AU (John Max Skaller) writes:
...
|>  How does this affect overloading?


As far as I know, the ANSI committee has not finished its work with this language extension.

Andrew Koenig suggested a reasonable ranking rule, that provides a partial ordering analagous to the rule for mapping pointer (or reference) to derived class to a pointer (or reference) to a base class.

All valid conversions formed by adding "const" or "volatile" to a type rank the same EXCEPT that a conversion is poorer than another valid conversion with a proper subset of the added attributes.

e.g. char ** -> char * const * is better than char ** -> const char * const *, but both conversions would rank equal with char ** -> char * volatile *.




Author: hopps@yellow.mmm.com (Kevin J Hopps)
Date: Thu, 12 Aug 93 17:29:07 GMT
Raw View
I asked my compiler supplier why I can no longer pass a (char**) to a
function expecting a (const char* const*).  This was the reply:

Alas, this isn't a bug in our compilers.  It is a 'feature' of the ANSI
C Standard.  Essentially, when we wrote the rules for where const and volatile
keywords can be 'tacked on' during a conversion, we only specified that you
could do so to one level of pointer.  Thus, you could declare echo to accept a
char *const *, but not what you've written. ...

Is this true?

If so, why can I not write a function which "accepts a char** but promises
to change neither the pointers nor the characters they point at?"
--
Kevin J. Hopps   e-mail: kjhopps@mmm.com
3M Company   phone: (612) 737-3300
3M Center, Bldg. 235-3B-16 fax: (612) 737-2700
St. Paul, MN 55144-1000




Author: kanze@us-es.sel.de (James Kanze)
Date: 13 Aug 93 16:32:34
Raw View
In article <hopps.745175689@mmm.com> hopps@yellow.mmm.com (Kevin J
Hopps) writes:

|> I asked my compiler supplier why I can no longer pass a (char**) to a
|> function expecting a (const char* const*).  This was the reply:

|> Alas, this isn't a bug in our compilers.  It is a 'feature' of the ANSI
|> C Standard.  Essentially, when we wrote the rules for where const and volatile
|> keywords can be 'tacked on' during a conversion, we only specified that you
|> could do so to one level of pointer.  Thus, you could declare echo to accept a
|> char *const *, but not what you've written. ...

|> Is this true?

Yes.  Or it was until a couple of months ago.

The rule was introduced to prevent the security leak caused by passing
a (char**) to a (const char**).  Regretfully, it covered too much.
The C++ standards committee has corrected this in C++, but it will no
doubt take a while until the correction gets into commercial compilers.
--
James Kanze                             email: kanze@us-es.sel.de
GABI Software, Sarl., 8 rue du Faisan, F-67000 Strasbourg, France
Conseils en informatique industrielle --
                   -- Beratung in industrieller Datenverarbeitung