Go Back   Rhinocerus > Newsgroup > Newsgroup comp.language.c++ > Newsgroup comp.language.c++.moderated

Reply
 
Thread Tools Display Modes
  #16 (permalink)  
Old 11-01-2005, 08:46 AM
Tim Roberts
Guest
 
Posts: n/a
Default Re: How to cast (char *) to (char *)& for a "call by reference" argument?

"Jerry" <rrrshop@hotmail.com> wrote:

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


The reason it's not castable is that there is no way to do it. Look:

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

This wants a reference to a pointer.

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

Here, you have an array. There IS no pointer, so there is no way to create
a reference to one, without creating a temporary pointer to contain the
address.

Even though they can often be used interchangeably, there is a significant
difference between these two variables:

char * StringA = "MyPath";
char StringB[] = "MyPath";

The variable "StringA" is a pointer. It is exactly 4 bytes long. It
contains an address, which happens to point to a 7-byte string, somewhere
in the string constant pool.

The variable "StringB" is an array of char. It is exactly 7 bytes long.
There is NO piece of memory that contains the address of the first "M" in
the second string, so you cannot create a reference to such a thing.
--
- Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.

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

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #17 (permalink)  
Old 11-02-2005, 10:39 AM
kanze
Guest
 
Posts: n/a
Default Re: How to cast (char *) to (char *)& for a "call by reference" argument?

Tim Roberts wrote:
> "Jerry" <rrrshop@hotmail.com> wrote:


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


> The reason it's not castable is that there is no way to do it.
> Look:


Sure there is. The real question is rather whether the
semantics correspond to anything useful.

IMHO, the question itself is poorly formulated. A cast is a
means, not an end. And without knowing the end, it's really
impossible to say what the best means are.

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


> This wants a reference to a pointer.


> int main(int argc, char* argv[])
> {
> char PathA[] = "MyPath";


> Here, you have an array. There IS no pointer, so there is no
> way to create a reference to one, without creating a temporary
> pointer to contain the address.


There *is* an implicit conversion of array to pointer, which
results in a pointer. As you say, however, this pointer is a
temporary (an rvalue, in C++-speak). As such, it cannot be
bound to a non-const reference.

As other posters have pointed out, if the function signature
were "void foo( char *const& )", there would be no problem. You
can also force things: static_cast< char *const& >( PathA )
creates a temporary reference to const, with the temporary
pointer (or a copy thereof) bound to it. The result of a
static_cast to a reference type is an lvalue, so you can use
const_cast on it, and still get an lvalue. So something like:

foo( const_cast< char*& >(
static_cast< char* const& >( PathA ) ) ) ;

should compile. If foo attempts to modify Path in anyway,
however, it will result in undefined behavior. (And of course,
if foo doesn't attempt to modify Path, then the reference should
be to a const, i.e.: "foo( char *const& Path )". Except that I
can't see any reason to do this, rather than simply "foo( char*
Path )".)

> Even though they can often be used interchangeably, there is a
> significant difference between these two variables:


> char * StringA = "MyPath";
> char StringB[] = "MyPath";


> The variable "StringA" is a pointer. It is exactly 4 bytes
> long.


You mean 8 bytes long, don't you. At least, that's what it is
on my machine. In fact, of course, it is implementation
defined; it's 4 bytes on a PC, but most modern architectures
(including top of the line PC's) also support 8 bytes, and older
machines have also used 2 and 6 (and some embedded processors
use 1).

More importantly, in the first example:

1. The pointer can be changed. You can later write StringA =
"Something else", or even StringA = StringB. You can'd do
this with StringB.

2. The initialization involves a deprecated implicit
conversion, which should be avoided in modern code. The
correct declaration would be:
char const* StringA = "MyPath" ;
Any attempt to modify the string itself through the pointer
(e.g. *StringA = 'x', or StringA[2] = 'y') is undefined
behavior.

In fact, the first definition creates two objects, a pointer to
a character, which is the object names StringA, and an unnamed
const array of 7 char, which is used to initialize the pointer.
The second definition creates a single object, a non const array
of 7 char, initialized with the characters in the string.

> It contains an address, which happens to point to a
> 7-byte string, somewhere in the string constant pool.


> The variable "StringB" is an array of char. It is exactly 7
> bytes long. There is NO piece of memory that contains the
> address of the first "M" in the second string, so you cannot
> create a reference to such a thing.


There is no named piece of memory which contains the address,
but it is pretty easy to get a temporary which contains it.

The status of temporaries of non-const types is a bit ambiguous.
They aren't necessarily "memory" (an "object", in the language
of the standard), except when they are. (Actually, the standard
is fairly precise. It speaks of the results of an expression as
lvalues and rvalues, rather than "temporaries". An rvalue of
non-class type is not an object; a temporary is an (unnamed)
object. In this case, the temporary is constructed by copying
the rvalue into the object. Intuitively, you might say that an
rvalue is something that might be in a register, but a temporary
must be in memory. Conceptually, of course, before
optimization.)

--
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! ]

Reply With Quote
 
Reply

Thread Tools
Display Modes

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 Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: converting char to num and num to char in datastep Gerstle, John Newsgroup comp.soft-sys.sas 0 05-02-2006 06:44 PM
Re: How to build Dynamic Variable names and values Arthur Tabachneck Newsgroup comp.soft-sys.sas 0 02-11-2006 06:34 PM
Re: How to build Dynamic Variable names and values SUBSCRIBE SAS-L Chandra Gadde Newsgroup comp.soft-sys.sas 0 02-11-2006 03:50 PM
Re: Splitting Char var into two Char vars w Space as Delimiter Terjeson, Mark Newsgroup comp.soft-sys.sas 0 09-27-2005 07:41 PM
Proc Report using RTF Out of Memory (8.1) on Mainframe McDonald, John M Newsgroup comp.soft-sys.sas 0 08-06-2005 06:25 PM



All times are GMT. The time now is 09:56 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.