 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
bruceteen@gmail.com Guest
|
Posted: Tue Dec 06, 2005 10:38 am Post subject: Invalid conversion from `char**' to `const char**' |
|
|
int main( void )
{
char** p1 = 0;
const char** p2 = p1;
}
compile error: invalid conversion from `char**' to `const char**'.
Why?Please!
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ulrich Eckhardt Guest
|
Posted: Tue Dec 06, 2005 1:35 pm Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
[email]bruceteen (AT) gmail (DOT) com[/email] wrote:
| Quote: | char** p1 = 0;
const char** p2 = p1;
compile error: invalid conversion from `char**' to `const char**'.
|
// a pointer to a non-const character
char* p;
// a pointer to a pointer to a non-const character
// assignment to '*pp' changes 'p'
char** pp = &p;
// a pointer to a pointer to a const character
// assignment to '*cpp' changes 'p'
char const** cpp = pp;
// a pointer to const character
char const* x;
// assign (indirectly) to 'p'
*cpp = x;
// change what 'x' points to
p[0] = 'y';
The last part obviously breaks const correctness, which is why there is no
conversion from 'T**' to 'T const**' in C++.
Uli
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ralf Fassel Guest
|
Posted: Tue Dec 06, 2005 6:11 pm Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
* [email]bruceteen (AT) gmail (DOT) com[/email]
| Quote: | compile error: invalid conversion from `char**' to `const char**'.
Why?Please!
|
Because you need
const char* const* p2;
R'
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
david francis Guest
|
Posted: Tue Dec 06, 2005 6:11 pm Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
gday,
basically the compiler is telling you that you are trying to equate two
different types, even though they are both chars, and compilers generally
dont like you doing that. the simple (but messy) solution is just to do a
simple type cast when you assign the right hand side as follows:
int main( void )
{
char** p1 = 0;
const char** p2 = (const char **) p1;
}
and your problem should be fixed (it works on my comp - vs 02). also, it's
generally more accepted to declare pointers as NULL instead of 0, even
though NULL is defined as 0. the world works in mysterious ways.
<bruceteen (AT) gmail (DOT) com> wrote
| Quote: | int main( void )
{
char** p1 = 0;
const char** p2 = p1;
}
compile error: invalid conversion from `char**' to `const char**'.
Why?Please!
|
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vince Morgan Guest
|
Posted: Tue Dec 06, 2005 6:15 pm Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
<bruceteen (AT) gmail (DOT) com> wrote
| Quote: | int main( void )
{
char** p1 = 0;
const char** p2 = p1;
|
You're trying to lie to the compiler and it caught you.
When you declare a pointer to a const object (object in it's broadest
def.)you are effectively claiming you will point it at a const object.
Above you try to point it at a non const object but the compiler won't let
you get away with it.
| Quote: | }
compile error: invalid conversion from `char**' to `const char**'.
Why?Please!
|
--
HTH
Vince Morgan
Remove UNSPAM
[email]vinhar (AT) UNSPAMoptusnet (DOT) com.au[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Greg Herlihy Guest
|
Posted: Wed Dec 07, 2005 2:42 pm Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
Vince Morgan wrote:
| Quote: | bruceteen (AT) gmail (DOT) com> wrote in message
news:1133853448.182137.265070 (AT) g49g2000cwa (DOT) googlegroups.com...
int main( void )
{
char** p1 = 0;
const char** p2 = p1;
You're trying to lie to the compiler and it caught you.
When you declare a pointer to a const object (object in it's broadest
def.)you are effectively claiming you will point it at a const object.
Above you try to point it at a non const object but the compiler won't let
you get away with it.
|
No, it's the other way around: the program is being truthful and it is
the compiler that is telling "lies" when it refuses to compile this
program.
After all, the program is perfectly honest: it has a char ** pointer,
and a char** pointer is exactly what it tries to pass to the function
that accepts a const char ** pointer. The compiler by refusing to
perform the conversion is in effect telling the user that either
non-const to const conversions are not allowed in C++ or that the
conversion in this case is somehow unsafe. Neither explanation is true.
Non-const to const implicit pointer conversions are always allowed in
C++. After all, what is the danger of passing a pointer to a modifiable
object to a routine that promises not to modify that object? There is
none. And in fact that description applies equally well to this
function call, the extra layer of indirection notwithstanding. What is
the danger being averted here? How is this code any less safe than
passing a char * to a routine that accepts a const char * - which it is
perfectly legal to do in a C++ program? The answer is that there is no
material difference between the two. And the compiler, by accepting one
case and rejecting the other, falsely implies the contrary.
So why doesn't the original program compile? The answer is that were
such a conversion allowed in any context, then it would be possible to
inadvertently circumvent the const protection afforded to the
const-declared, indirectly-referenced object. Morever, because C++ does
not distinguish between different contexts when it comes to conversions
- to allow an implicit conversion for this type of function call means
that it would have to be allowed everywhere else - including those
contexts in which it could cause a problem.
In other words, the biggest "lie" that the compiler tells, is to claim
that there is something wrong with this program. But the much stronger
case to be made is that there really is nothing wrong with the program,
but with the language. The defect here is C++'s need for a more nuanced
approach to implicit conversions that would distinguish when such a
conversion could be done - and when it could not be done - safely.
Greg
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Ralf Fassel Guest
|
Posted: Wed Dec 07, 2005 6:48 pm Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
* "Greg Herlihy" <greghe (AT) pacbell (DOT) net>
| Quote: | Vince Morgan wrote:
char** p1 = 0;
const char** p2 = p1;
|
Strictly spoken, while all the pointers are 0, you can't do anything
with them. So the above should be ok, if the pointers are left at 0.
| Quote: | After all, what is the danger of passing a pointer to a modifiable
object to a routine that promises not to modify that object?
|
It promises not to modify the _final_ thing which the pointers point
to, but not the _intermediate_ thing (the array of pointers, since
they are *not* const). So it could put some 'pointers to const' into
*p2, and afterwards **p1 could be used to change the const objects:
char **p1 = new char*[1];
const char **p2 = (const char **)p1; // bogus cast
const char a = 'x';
*p2 = &a;
std::cout << ('x' == **p2) << std::endl; // true
**p1 = 'y'; // boom
std::cout << ('x' == **p2) << std::endl; // FALSE
| Quote: | How is this code any less safe than passing a char * to a routine
that accepts a const char * - which it is perfectly legal to do in a
C++ program? The answer is that there is no material difference
between the two.
|
Yes, there is. It is the intermediate layer of pointers in a char**
which is the 'dangerous' part, not the final pointers themselves.
| Quote: | So why doesn't the original program compile? The answer is that were
such a conversion allowed in any context, then it would be possible
to inadvertently circumvent the const protection afforded to the
const-declared, indirectly-referenced object.
|
I don't understand... first you say it is not a problem, now you say
it *is* a problem?
R'
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
kanze Guest
|
Posted: Thu Dec 08, 2005 12:47 pm Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
Greg Herlihy wrote:
| Quote: | Vince Morgan wrote:
[email]bruceteen (AT) gmail (DOT) com[/email]> wrote in message
news:1133853448.182137.265070 (AT) g49g2000cwa (DOT) googlegroups.com...
int main( void )
{
char** p1 = 0;
const char** p2 = p1;
You're trying to lie to the compiler and it caught you. When
you declare a pointer to a const object (object in it's
broadest def.)you are effectively claiming you will point it
at a const object. Above you try to point it at a non const
object but the compiler won't let you get away with it.
No, it's the other way around: the program is being truthful
and it is the compiler that is telling "lies" when it refuses
to compile this program.
|
I don't think lying comes into the argument here. The original
poster is trying to do something that is illegal. The compiler
complains about it. That's all. The orginal programmer doesn't
tell the compiler anything which isn't true. And the compiler
does its job as well, refusing something that is forbidden by
the standard without an explicit override (a cast) because it
"breaks const".
| Quote: | After all, the program is perfectly honest: it has a char **
pointer, and a char** pointer is exactly what it tries to pass
to the function that accepts a const char ** pointer. The
compiler by refusing to perform the conversion is in effect
telling the user that either non-const to const conversions
are not allowed in C++ or that the conversion in this case is
somehow unsafe. Neither explanation is true.
|
The compiler is telling the programmer that the conversion
char** to char const** is not allowed as an implicit conversion
in C++. This is perfectly true; the only qualification
conversions allowed here are char** to char *const* and char**
to char const* const*. (Only the first is allowed in C.) Since
the target is neither of these types, the code is illegal.
| Quote: | Non-const to const implicit pointer conversions are always
allowed in C++.
|
More explicitly, T* to T const* is always allowed in C++. But
that's not what he's doing. He's trying to do a T* to T'*,
where T' has an internal const when compared to T. And that
isn't allowed.
| Quote: | After all, what is the danger of passing a pointer to a
modifiable object to a routine that promises not to modify
that object?
|
None, but that's not what is being done here.
| Quote: | There is none. And in fact that description applies equally
well to this function call, the extra layer of indirection
notwithstanding.
|
The extra level of indirection changes everything. If this were
allowed, I could use *p2 to assign a char const* to a char*, and
then modify the (probably const) data, e.g.:
char const* p1 = "xxx" ;
char* p2 ;
char const** pp = &p2 ; // <=== illegal !!!
*pp = p1 ;
*p2 = 'a' ; // because this would modify a const.
| Quote: | What is the danger being averted here?
|
Silently removing const without the need of a const_cast.
| Quote: | How is this code any less safe than passing a char * to a
routine that accepts a const char * - which it is perfectly
legal to do in a C++ program? The answer is that there is no
material difference between the two. And the compiler, by
accepting one case and rejecting the other, falsely implies
the contrary.
|
I don't think the compiler implies anything. It's just
following the C++ standard. The rules are there for a purpose.
(The C++ rules are actually more liberal than the C rules here.)
| Quote: | So why doesn't the original program compile? The answer is
that were such a conversion allowed in any context, then it
would be possible to inadvertently circumvent the const
protection afforded to the const-declared,
indirectly-referenced object. Morever, because C++ does not
distinguish between different contexts when it comes to
conversions - to allow an implicit conversion for this type of
function call means that it would have to be allowed
everywhere else - including those contexts in which it could
cause a problem.
In other words, the biggest "lie" that the compiler tells, is
to claim that there is something wrong with this program. But
the much stronger case to be made is that there really is
nothing wrong with the program, but with the language. The
defect here is C++'s need for a more nuanced approach to
implicit conversions that would distinguish when such a
conversion could be done - and when it could not be done -
safely.
|
I'm not sure what you're arguing for. In the exact case here,
of course, there is no danger -- the pointer is null, so nothing
is going to be modified through it. But the language certainly
doesn't, and shouldn't, define the legality of an implicit
conversion according to the run-time values involved or the use
that is ultimately made of the converted value.
--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Vince Morgan Guest
|
Posted: Fri Dec 09, 2005 10:57 am Post subject: Re: Invalid conversion from `char**' to `const char**' |
|
|
"Vince Morgan" <vinhar (AT) UNSPAMoptusnet (DOT) com.au> wrote
| Quote: | bruceteen (AT) gmail (DOT) com> wrote in message
news:1133853448.182137.265070 (AT) g49g2000cwa (DOT) googlegroups.com...
int main( void )
{
char** p1 = 0;
const char** p2 = p1;
You're trying to lie to the compiler and it caught you.
When you declare a pointer to a const object (object in it's broadest
def.)you are effectively claiming you will point it at a const object.
Above you try to point it at a non const object but the compiler won't let
you get away with it.
The answer I gave was more than a little trite, and certainly ambiguous. |
Suggesting intent was foolishness, and possibly insulting, though it was
meant in jest.
Thank you to those who pointed this out.
Please accept my appologies Bruce.
--
Vince Morgan
Remove UNSPAM
[email]vinhar (AT) UNSPAMoptusnet (DOT) com.au[/email]
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|