Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   this cast to const char* (http://www.velocityreviews.com/forums/t747817-this-cast-to-const-char.html)

Gernot Frisch 05-05-2011 05:27 PM

this cast to const char*
 
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



Kai-Uwe Bux 05-05-2011 05:39 PM

Re: this cast to const char*
 
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

Felix Bytow 05-05-2011 05:40 PM

Re: this cast to const char*
 
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

Öö Tiib 05-05-2011 05:44 PM

Re: this cast to const char*
 
On May 5, 8:27*pm, "Gernot Frisch" <m...@privacy.net> 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.

gwowen 05-05-2011 05:50 PM

Re: this cast to const char*
 
On May 5, 6:27*pm, "Gernot Frisch" <m...@privacy.net> 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...

Öö Tiib 05-05-2011 05:52 PM

Re: this cast to const char*
 
On May 5, 8:40*pm, Felix Bytow <felix.by...@informatik.tu-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.

Öö Tiib 05-05-2011 05:58 PM

Re: this cast to const char*
 
On May 5, 8:50*pm, gwowen <gwo...@gmail.com> wrote:
> On May 5, 6:27*pm, "Gernot Frisch" <m...@privacy.net> 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.


Bo Persson 05-05-2011 06:21 PM

Re: this cast to const char*
 
Öö Tiib wrote:
> On May 5, 8:50 pm, gwowen <gwo...@gmail.com> wrote:
>> On May 5, 6:27 pm, "Gernot Frisch" <m...@privacy.net> 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



gwowen 05-05-2011 06:27 PM

Re: this cast to const char*
 
On May 5, 6:58*pm, Öö Tiib <oot...@hot.ee> wrote:

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


For single inheritance, thats a distinction without a difference.

Öö Tiib 05-05-2011 06:37 PM

Re: this cast to const char*
 
On May 5, 9:27*pm, gwowen <gwo...@gmail.com> wrote:
> On May 5, 6:58*pm, Öö Tiib <oot...@hot.ee> 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?


All times are GMT. The time now is 05:01 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.