What does the object name represent?

P

Phil Ward

The following has recently arose and it is the first time I have noticed
this behaviour.

I have been using a self-defined string class. It's form is

class CMyString
{
public:
... (no public varaibles)
...
operator char* () const { return mpChar; }

private:
char* mpChar;
unsigned long mBytesAllocated;
};


Obviously the purpose of the casting operator is to be able to use the
object much like a null terminated c-string.

The following code is ok:

char Buff[100];
CMyString MyString("Hello");

strcpy(Buff, (char*) MyString);


Something interesting happens if the cast operator is (accidently) omitted.

strcpy(Buff, MyString);


This code compiles and links without warning. Lint does warn that the second
argument is not a pointer.
However, this code executes and Buff end up with the value "Hello". It
appears that the object name is interpreted
as a pointer to the mpChar private data member. If the specificiation order
of mpChar and mBytesAllocated
is reversed, the code again compiles and links but will crash on execution.

My conclusion is that the name of an object is a pointer to the first(?)
class data member. I have never seen this
mentioned in the literature. Is this common knowledge and I have just missed
it? I would not have immediately
caught this without lint and, in some ways, it appear dangerous.

Thanks for any comments.

Phil Ward
 
V

Victor Bazarov

Phil said:
The following has recently arose and it is the first time I have
noticed this behaviour.

I have been using a self-defined string class. It's form is

class CMyString
{
public:
... (no public varaibles)
...

What does a c-tor look like? Did you follow "The Rule of Three"?
operator char* () const { return mpChar; }

Bad idea. You should do

operator const char*() const { reutrn mpChar; }

otherwise you are opening a door to modify the "contents" of an object
you deem 'const'.
private:
char* mpChar;
unsigned long mBytesAllocated;
};


Obviously the purpose of the casting operator is to be able to use the
object much like a null terminated c-string.

The following code is ok:

char Buff[100];
CMyString MyString("Hello");

strcpy(Buff, (char*) MyString);


Something interesting happens if the cast operator is (accidently)
omitted.
strcpy(Buff, MyString);


This code compiles and links without warning. Lint does warn that the
second argument is not a pointer.
However, this code executes and Buff end up with the value "Hello". It
appears that the object name is interpreted
as a pointer to the mpChar private data member. If the specificiation
order of mpChar and mBytesAllocated
is reversed, the code again compiles and links but will crash on
execution.

That's more interesting. Have you tried investigating?
My conclusion is that the name of an object is a pointer to the
first(?) class data member.

Huh? Never heard of it. Your conversion function is used. But it
should be used in both cases.
I have never seen this
mentioned in the literature. Is this common knowledge and I have just
missed it? I would not have immediately
caught this without lint and, in some ways, it appear dangerous.

V
 
P

Phil Ward

Ok - I think I have partially figured out. It seems that when performing

strcpy(Buff, MyString), that the compiler is employing an implicit cast
using the
(char*) operator. That is neat, but I will have to bone up on implicit
casting.

My appologies, but the crash I described earlier is incorrect.

Victor Bazarov said:
Phil said:
The following has recently arose and it is the first time I have
noticed this behaviour.

I have been using a self-defined string class. It's form is

class CMyString
{
public:
... (no public varaibles)
...

What does a c-tor look like? Did you follow "The Rule of Three"?
operator char* () const { return mpChar; }

Bad idea. You should do

operator const char*() const { reutrn mpChar; }

otherwise you are opening a door to modify the "contents" of an object
you deem 'const'.
private:
char* mpChar;
unsigned long mBytesAllocated;
};


Obviously the purpose of the casting operator is to be able to use the
object much like a null terminated c-string.

The following code is ok:

char Buff[100];
CMyString MyString("Hello");

strcpy(Buff, (char*) MyString);


Something interesting happens if the cast operator is (accidently)
omitted.
strcpy(Buff, MyString);


This code compiles and links without warning. Lint does warn that the
second argument is not a pointer.
However, this code executes and Buff end up with the value "Hello". It
appears that the object name is interpreted
as a pointer to the mpChar private data member. If the specificiation
order of mpChar and mBytesAllocated
is reversed, the code again compiles and links but will crash on
execution.

That's more interesting. Have you tried investigating?
My conclusion is that the name of an object is a pointer to the
first(?) class data member.

Huh? Never heard of it. Your conversion function is used. But it
should be used in both cases.
I have never seen this
mentioned in the literature. Is this common knowledge and I have just
missed it? I would not have immediately
caught this without lint and, in some ways, it appear dangerous.

V
 
D

David Harmon

On Thu, 02 Nov 2006 18:12:44 GMT in comp.lang.c++, "Phil Ward"
Ok - I think I have partially figured out. It seems that when performing

strcpy(Buff, MyString), that the compiler is employing an implicit cast
using the
(char*) operator. That is neat, but I will have to bone up on implicit
casting.

That is exactly what you are asking for by defining that operator.
If you want to access the pointer explicitly only (highly recommended)
then define a member function with some name that you choose, like
c_str(), that cannot bite you implicitly.
My appologies, but the crash I described earlier is incorrect.

You crashed because you strcpy() something to the class's buffer without
preparing to receive it. To help avoid that, if you keep the implicit
cast operator, at minimum make it

operator char const* () const;
 
K

Kaz Kylheku

Phil said:
The following has recently arose and it is the first time I have noticed
this behaviour.

I have been using a self-defined string class. It's form is

class CMyString
{
public:
... (no public varaibles)
...
operator char* () const { return mpChar; }

private:
char* mpChar;
unsigned long mBytesAllocated;
};


Obviously the purpose of the casting operator is to be able to use the
object much like a null terminated c-string.

The following code is ok:

char Buff[100];
CMyString MyString("Hello");

strcpy(Buff, (char*) MyString);


Something interesting happens if the cast operator is (accidently) omitted.

strcpy(Buff, MyString);

What's so interesting about it? There is a prototype of strcpy in
scope, which is:

char *strcpy(char *dest, const char *src);

MyString is an object of a class which has a char * operator, giving
rise for a way for that object to be converted to the parameter type.
This code compiles and links without warning. Lint does warn that the second
argument is not a pointer.

Find a properly written lint that understands C++ classes and
conversion rules.
My conclusion is that the name of an object is a pointer to the first(?)
class data member.

That's a silly conclusion, given that the class has an "operator char
*()" function staring you in the face, which you even reproduced for
the benefit of the newsgroup.
 
K

Kaz Kylheku

Phil said:
Ok - I think I have partially figured out. It seems that when performing

strcpy(Buff, MyString), that the compiler is employing an implicit cast
using the
(char*) operator. That is neat, but I will have to bone up on implicit
casting.

There is no such thing as an "implicit cast". It's simply a conversion.
A cast is an explicit conversion.

Implicit conversions are everywhere. The concept is inherited into C++
from C.

For instance:

int x = 3;
long y = 4;
double z = x + y;

Here, x is implicitly converted to type long, making it compatible for
addition with y. Then the result of the expression is implicitly
converted to double, so it can be assigned to z.

C++ provides ways for automatic conversion to and from class types
under programmer control, so that the same notational convenience can
be achieved when using objects.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,017
Latest member
GreenAcreCBDGummiesReview

Latest Threads

Top