C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

How to cast (char *) to (char *)& for a "call by reference"
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Jerry
Guest





PostPosted: Fri Oct 28, 2005 9:40 am    Post subject: How to cast (char *) to (char *)& for a "call by reference" Reply with quote



Here is the program:

void foo(char *& Path)
{
// Do something with szPath...
}
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error
return 0;
}
I got following error:
- error C2664: 'foo' : cannot convert parameter 1 from 'char [7]' to
'char *& '

Can somebody tell me how should I cast the PathA to get it working?

Thanks!
-J


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Stefan Näwe
Guest





PostPosted: Fri Oct 28, 2005 6:27 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by refere Reply with quote



Jerry wrote:

Quote:
Here is the program:

void foo(char *& Path)
{
// Do something with szPath...
}
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";


char* PathA = 0;
// Initialize PathA if needed (depends on what foo() will do)
// for example: PathA = strdup("MyPath");
// but don't forget to free(PathA)


Quote:
foo(PathA); // This call has compiling error
return 0;
}
I got following error:
- error C2664: 'foo' : cannot convert parameter 1 from 'char [7]' to
'char *& '

Can somebody tell me how should I cast the PathA to get it working?


Don't cast. Think about using a std::string.


Stefan
-- Stefan Naewe
naewe.s_AT_atlas_DOT_de

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Sebastian Redl
Guest





PostPosted: Sat Oct 29, 2005 3:47 am    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote



[Unrecognized group removed from header -- mod]
Jerry wrote:

Quote:
Here is the program:

void foo(char *& Path)
{
// Do something with szPath...
}
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error
return 0;
}

foo expects a non-const reference as the argument. Non-const references can
only bind to lvalues. However, the result of implicitely converting PathA
to (char*) is an rvalue (it has no memory address).
To make this call succeed, you need to introduce an extra char* variable:
int main(int argc, char *argv[])
{
char PathA[] = "MyPath";
char *pPathA = PathA;
foo(pPathA);
return 0;
}

Note that this is not necessarily what you want: foo can now change what
pPathA points to, but it could change the actual contents of PathA even
without the reference.

--
Sebastian Redl

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Joe
Guest





PostPosted: Sat Oct 29, 2005 1:02 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

Quote:

Can somebody tell me how should I cast the PathA to get it working?

Thanks!
-J

The short answer is you can't. You have foo() declared to take a
reference to a pointer and no matter how you shake it, pathA[] isn't a
pointer. It is an array.

If you think about it, the only reason to pass a reference to a pointer
would be because you intended to modify that pointer in foo(). What
would it mean to modify the beginning of an array? Maybe it would be
better to show you the memory layout implied by pointers and arrays
(Note: compilers can optimize all sorts of things, so this may not be
what you end up with, however it is the implied layout).

With an array you get something like:

pathA: <ch1><ch2>...<chn>

With a pointer you have:

pPathA: <address>
<address>: <ch1><ch2>...<chn>

In the first case, the token pathA refers to the address of the first
element of the array, in the pointer case, the token refers to a piece
of memory containing the address of the first element. The compiler
allows pathA to be treated as a pointer because of C compatibility and
the lack of any sort of string type in the base language. That is,
"Text" is an array (unless it is used for initialization) and it would
be inconvenient to always have to declare a pointer to every text
literal you might want.

So, if you really need foo() to take a reference to a pointer, then you
need to change pathA to:

char const * pathA = "Text";

then you can call foo(pathA). Personally, I would consider rewriting
foo() to accept a char const * instead of the reference.

joe


[ 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





PostPosted: Sat Oct 29, 2005 1:02 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

Jerry wrote:
Quote:
Here is the program:

void foo(char *& Path)
{
// Do something with szPath...

Presumably, you mean Path. And presumably, that something means
modifying the pointer (and not just what it points to),
something along the lines of:

Path = new char[ n ] ;

Quote:
}
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error

Which is to be expected: where is the pointer which is to be
modified.

Quote:
return 0;
}
I got following error:
- error C2664: 'foo' : cannot convert parameter 1 from 'char [7]' to
'char *& '

Can somebody tell me how should I cast the PathA to get it working?

Do you want to? The question above stands: where is the pointer
which is to be modified?

The normal way of handling this would be something like:

char PathA[] = "MyPath" ;
char* PathAPtr = PathA ;
foo( PathAPtr ) ;

Realizing, of course, that after the call to foo, PathAPtr may
not be equal to PathA.

--
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
xlxieliang@hotmail.com
Guest





PostPosted: Sat Oct 29, 2005 1:03 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

void foo(char *& Path)
{
// Do something with szPath...


}


int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo((char*&)PathA);
// This call has compiling error
return 0;

}

foo(((char*&)PathA) instead of foo(PathA);


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Thomas Maeder
Guest





PostPosted: Sat Oct 29, 2005 1:07 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

"Jerry" <rrrshop (AT) hotmail (DOT) com> writes:

Quote:
void foo(char *& Path)
{
// Do something with szPath...

That's hard; there is no szPath declared here.

Quote:
}

int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error
return 0;
}
I got following error:
- error C2664: 'foo' : cannot convert parameter 1 from 'char [7]' to
'char *& '

Can somebody tell me how should I cast the PathA to get it working?

Hardly. PathA is not a pointer.

What problem are you trying to solve?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Neelesh
Guest





PostPosted: Sat Oct 29, 2005 1:08 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

Jerry wrote:
Quote:
Here is the program:

void foo(char *& Path)
{
// Do something with szPath...
}
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error

when PathA is passed to foo, char[] is implicitly converted to char* by
generation of a temporary. A temporary can be passed as a const& but
not as a non-const& . Hence you need to change the prototype as

void foo(char * const & Path)// reference to a constant pointer to a
character.

Hope this helps.
Neelesh


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Allan W
Guest





PostPosted: Sat Oct 29, 2005 1:08 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

Jerry wrote:
Quote:
Here is the program:

void foo(char *& Path)
{
// Do something with szPath...
}

Hmm, you don't say what szPath is...

Quote:
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error
return 0;
}
I got following error:
- error C2664: 'foo' : cannot convert parameter 1 from 'char [7]' to
'char *& '

Foo's parameter is a reference to a pointer. You're passing in a
pointer, but not in a variable that can be referenced.

It's the same problem as this:
void bar(int &x) { x = 3; }
int baz() { bar(3+3); } // Error
Here, bar accepts a reference to an integer, so that it can
modify the integer. baz passes in an integer expression -- but
it isn't an integer variable, so it can't be modified.

Your program does the same thing. The parameter to foo needs to
be a variable of type char*, so that foo() can modify it. But
you're passing in an expression of type char*. There's nothing
for foo to modify.

Quote:
Can somebody tell me how should I cast the PathA to get it working?

You can't do it with a cast. You need a variable of type char*.

int main(int argc, char* argv[]) {
char PathA[] = "MyPath";
char*x = PathA;
foo(x);
return 0;
}

// ** OR **

int main(int argc, char* argv[]) {
char *PathA = "MyPath";
foo(PathA);
return 0;
}

Hope this explains it.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Carlos Moreno
Guest





PostPosted: Sat Oct 29, 2005 1:09 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

Jerry wrote:
Quote:
Here is the program:

void foo(char *& Path)
{
// Do something with szPath...
}
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error
return 0;
}
I got following error:
- error C2664: 'foo' : cannot convert parameter 1 from 'char [7]' to
'char *& '

Can somebody tell me how should I cast the PathA to get it working?

Well, what you're doing definitely seems wrong.

Don't know if the following is even an option for you, but
it works:

void foo (char * const & path)

As I said, maybe changing the function's signature is not an
option for you, but as a reference to const, implicit conversion
is allowed. In your original code, because it is a reference to
a 'char *', you require an actual char * to refer to, which the
array is not.

HTH,

Carlos
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
John Carson
Guest





PostPosted: Sat Oct 29, 2005 1:09 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

"Jerry" <rrrshop (AT) hotmail (DOT) com> wrote

Quote:
Here is the program:

void foo(char *& Path)
{
// Do something with szPath...
}

Don't cast. Change it to

void foo(char * const & Path)
{
// Do something with szPath...
}


Quote:
int main(int argc, char* argv[])
{
char PathA[] = "MyPath";
foo(PathA); // This call has compiling error
return 0;
}
I got following error:
- error C2664: 'foo' : cannot convert parameter 1 from 'char [7]' to
'char *& '

Can somebody tell me how should I cast the PathA to get it working?

The problem is that when you make the function parameter a reference to a
pointer, the function can change the value of the pointer that is passed as
an argument (as distinct from changing what the pointer points to).

If you then supply an array (rather than a pointer) as the function's
argument, the function definition would suggest that the function could
change the value of the array as if it were a pointer, which is impossible.

Thus the language requires that you declare that the pointer is const, so
that the function won't be changing it. An array can then legally be
converted to a pointer when passed as a function argument.

--
John Carson


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Jerry
Guest





PostPosted: Sat Oct 29, 2005 7:45 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

Stefan, thanks for your reply. But my goal it to learn how to cast the
PathA correctly. If it's not castable, why?


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
jeff_d_harper@hotmail.com
Guest





PostPosted: Sat Oct 29, 2005 7:47 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

The compiler complains because PathA is not a char pointer. It is a
char array. PathA can be used in many places where a char * type is
expected. However, one major difference between PathA and a normal
char * is that PathA cannot be modified to point to a different
address. Since foo takes a reference to a pointer, it could modify the
caller's pointer. Since PathA cannot be modified, the compiler must
complain.

Your example is similar to this:

void foo(int & x);
main()
{
foo(3); // <- the compiler will complain here because
// the literal 3 cannot be modified. However,
// foo is allowed to change the int passed by the
// caller.
}

You can make your code compile by changing the declaration of PathA to
make it a char *:

char *PathA = "MyPath";

It is a little bit unusual (though not unheard of) to pass references
to pointers. Instead of making changes in main, you might be able to
change the declaration of foo to make it more usable. Unless foo needs
to change the caller's pointer, it's declaration could be changed to
accept a char *:

void foo(char * Path) ;


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Back to top
Niklas Matthies
Guest





PostPosted: Sun Oct 30, 2005 3:32 am    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

On 2005-10-29 19:45, Jerry wrote:
Quote:
Stefan, thanks for your reply. But my goal it to learn how to cast the
PathA correctly. If it's not castable, why?

It is castable, that is not the problem. The problem is that casting
only creates a temporary object (of type 'char *'), and C++ doesn't
allow temporary objects to be bound to non-const references.
It will work if you change foo() to 'void foo(char * const & path)'.

-- Niklas Matthies

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Carlos Moreno
Guest





PostPosted: Sun Oct 30, 2005 3:02 pm    Post subject: Re: How to cast (char *) to (char *)& for a "call by referen Reply with quote

Jerry wrote:
Quote:
Stefan, thanks for your reply. But my goal it to learn how to cast the
PathA correctly. If it's not castable, why?

Jerry,

Be very careful with this. Usually, when the compiler does not
allow you to do something, it is because that something is not
possible, or it is wrong.

The fact that you are passing a char * by reference *most likely*
means that you need to modify the pointer inside the function
(and have that change modified in the client code's pointer
that was passed to the function).

If that is not the case, then your function is poorly designed,
and you should not pass the parameter by reference.

Now, if you do want to modify the pointer, and thus need to
pass by reference, then you have to have *an actual pointer*
to refer to, and not a temporary thing that is the outcome
of an implicit conversion and that does not physically
exist in the data of your program. You requrie something
like a variable of type 'char *', so that when you refer
to it and modify it, the operation is meaningful. A char
array *is not* a pointer; you can not have a reference-to-
pointer refer to this, because this is an object that is
physically different from a pointer.

If you pass by value (the value of the pointer), then
everything is ok, since the implicit conversion from array
to pointer allows the compiler to temporarily create a
pointer, by taking the address of the first element of
the array, and pass that value (that memory address) to
the function.

Same thing happens if you pass by reference-to-const, since
that means that the function is not going to modify the
referred pointer, so the compiler is happy with passing a
reference to the temporary "ficticious" pointer.

Again: the important thing is, make an effort to understand
what's really happening in your program, instead of making
an effort in learning how to *force* the compiler to do
something that is wrong and that will lead you to no good.

HTH,

Carlos
--

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.