Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > this cast to const char*

Reply
Thread Tools

this cast to const char*

 
 
Gernot Frisch
Guest
Posts: n/a
 
      05-05-2011
Hi,

with "MFC" I can do:
CString str(_T("test"); printf("%s", str); // prints "test"

With my own string class, however, there seems to be a 4 byte "header"
before the string data.

I have the member >const TCHAR* m_data;< as the first member of my string
class.

How does MS doe this?

Thank you,
-Gernot


 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      05-05-2011
Gernot Frisch wrote:

> with "MFC" I can do:
> CString str(_T("test"); printf("%s", str); // prints "test"
>
> With my own string class, however, there seems to be a 4 byte "header"
> before the string data.
>
> I have the member >const TCHAR* m_data;< as the first member of my string
> class.
>
> How does MS doe this?


First, MS could use compiler magic to define the UB of the first line. With
your own (homegrown) string class, any use of printf would be UB (the specs
of printf simply won't know about your string class).

Second, I doubt that MS actually does use compiler magic and the first line
could just "work" by accident. Question: does your string class have a
virtual method (e.g., the destructor)? does the CString class?


Best,

Kai-Uwe Bux
 
Reply With Quote
 
 
 
 
Felix Bytow
Guest
Posts: n/a
 
      05-05-2011
hi,

> with "MFC" I can do:
> CString str(_T("test"); printf("%s", str); // prints "test"
>
> With my own string class, however, there seems to be a 4 byte "header"
> before the string data.
>
> I have the member >const TCHAR* m_data;< as the first member of my
> string class.
>
> How does MS doe this?
>


MS provides a casting operator for that.
When writing a class you can define your own casting operators.

e.g.:
class str
{
char *buff;
// some stuff

// here comes the casting operator
operator const char * (void) const
{
return buff;
}
};

this way an object of "str" will be implicitly casted to const char * if
needed.
you could also declare it "explicit" though

within your own casting operators you can also do some more complex
stuff than simply returning a member of your class.

I hope I helped you

Felix
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      05-05-2011
On May 5, 8:27*pm, "Gernot Frisch" <(E-Mail Removed)> wrote:
> Hi,
>
> with "MFC" I can do:
> CString str(_T("test"); printf("%s", str); // prints "test"


Note that all good compilers and MS own static code analyser "prefast"
complain against using class type object as printf argument.

> With my own string class, however, there seems to be a 4 byte "header"
> before the string data.
>
> I have the member >const TCHAR* m_data;< as the first member of my string
> class.
>
> How does MS doe this?


Likely by not having any virtual functions in their CString so it has
no vtable. Who cares? It is wrong anyway.
 
Reply With Quote
 
gwowen
Guest
Posts: n/a
 
      05-05-2011
On May 5, 6:27*pm, "Gernot Frisch" <(E-Mail Removed)> wrote:
> Hi,
>
> with "MFC" I can do:
> CString str(_T("test"); printf("%s", str); // prints "test"
>
> With my own string class, however, there seems to be a 4 byte "header"
> before the string data.
>
> I have the member >const TCHAR* m_data;< as the first member of my string
> class.


Passing C++ classes to variable argument functions like printf() is
not advisable ... but if you *MUST* you can have your class inherit
from a POD type with the m_data with its only (or first) member. This
will force your non-POD class to be layout compatible, and so the
"header" (which will probably be the table of function pointers for
virtual dispatch). This will almost certainly work, as long as the
size of m_data matches the size of argument the compiler expects for
vararg functions...
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      05-05-2011
On May 5, 8:40*pm, Felix Bytow <(E-Mail Removed)-chemnitz.de>
wrote:
> hi,
>
> > with "MFC" I can do:
> > CString str(_T("test"); printf("%s", str); // prints "test"

>
> > With my own string class, however, there seems to be a 4 byte "header"
> > before the string data.

>
> > I have the member >const TCHAR* m_data;< as the first member of my
> > string class.

>
> > How does MS doe this?

>
> MS provides a casting operator for that.
> When writing a class you can define your own casting operators.
>
> e.g.:
> class str
> {
> * * * * char *buff;
> * * * * // some stuff
>
> * * * * // here comes the casting operator
> * * * * operator const char * (void) const
> * * * * {
> * * * * * * * * return buff;
> * * * * }
>
> };
>
> this way an object of "str" will be implicitly casted to const char * if
> needed.
> you could also declare it "explicit" though
>
> within your own casting operators you can also do some more complex
> stuff than simply returning a member of your class.


Nope, you are wrong. To use the casting operator you need to write:

CString str(_T("test"); printf("%s", (LPCTSTR)str);

It works just by accident, like Kai-Uwe said.

Such implicit casting operators actually make CString dangerous to
use, so if you use MFC for GUI then keep the CString strictly inside
of your GUI classes.
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      05-05-2011
On May 5, 8:50*pm, gwowen <(E-Mail Removed)> wrote:
> On May 5, 6:27*pm, "Gernot Frisch" <(E-Mail Removed)> wrote:
>
> > Hi,

>
> > with "MFC" I can do:
> > CString str(_T("test"); printf("%s", str); // prints "test"

>
> > With my own string class, however, there seems to be a 4 byte "header"
> > before the string data.

>
> > I have the member >const TCHAR* m_data;< as the first member of my string
> > class.

>
> Passing C++ classes to variable argument functions like printf() is
> not advisable ... but if you *MUST* you can have your class inherit
> from a POD type with the m_data with its only (or first) member. *This
> will force your non-POD class to be layout compatible, and so the
> "header" (which will probably be the table of function pointers for
> virtual dispatch). This will almost certainly work, as long as the
> size of m_data matches the size of argument the compiler expects for
> vararg functions...


It will force only POD base subobject to be layout compatible (and
printf does not cast argument to that base) so if it works then again
by accident.

 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      05-05-2011
Öö Tiib wrote:
> On May 5, 8:50 pm, gwowen <(E-Mail Removed)> wrote:
>> On May 5, 6:27 pm, "Gernot Frisch" <(E-Mail Removed)> wrote:
>>
>>> Hi,

>>
>>> with "MFC" I can do:
>>> CString str(_T("test"); printf("%s", str); // prints "test"

>>
>>> With my own string class, however, there seems to be a 4 byte
>>> "header" before the string data.

>>
>>> I have the member >const TCHAR* m_data;< as the first member of
>>> my string class.

>>
>> Passing C++ classes to variable argument functions like printf() is
>> not advisable ... but if you *MUST* you can have your class inherit
>> from a POD type with the m_data with its only (or first) member.
>> This will force your non-POD class to be layout compatible, and so
>> the "header" (which will probably be the table of function
>> pointers for virtual dispatch). This will almost certainly work,
>> as long as the size of m_data matches the size of argument the
>> compiler expects for vararg functions...

>
> It will force only POD base subobject to be layout compatible (and
> printf does not cast argument to that base) so if it works then
> again by accident.


It actually isn't by accident (not anymore, at least), MS has
documented that passing a CString by value gets you the pointer to
your string. They don't dare to break all the printfs already
existing!


Bo Persson


 
Reply With Quote
 
gwowen
Guest
Posts: n/a
 
      05-05-2011
On May 5, 6:58*pm, Öö Tiib <(E-Mail Removed)> wrote:

> It will force only POD base subobject to be layout compatible


For single inheritance, thats a distinction without a difference.
 
Reply With Quote
 
Öö Tiib
Guest
Posts: n/a
 
      05-05-2011
On May 5, 9:27*pm, gwowen <(E-Mail Removed)> wrote:
> On May 5, 6:58*pm, Öö Tiib <(E-Mail Removed)> wrote:
>
> > It will force only POD base subobject to be layout compatible

>
> For single inheritance, thats a distinction without a difference.


Hmm ... really? Where does standard say that POD base sub-object when
used with single inheritance should be located at very start of object
of derived class?
 
Reply With Quote
 
 
 
Reply

Thread Tools

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 PM
const correctness - should C++ prefer const member over non-const? fungus C++ 13 10-31-2008 05:33 AM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM
error C2440: 'return' : cannot convert from 'const char *' to 'const unsigned short *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast Abhijit Bhadra C++ 2 12-01-2004 04:43 PM



Advertisments