Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #4726 > unrolled thread
| Started by | "Gernot Frisch" <me@privacy.net> |
|---|---|
| First post | 2011-05-05 19:27 +0200 |
| Last post | 2011-05-09 09:40 -0700 |
| Articles | 10 on this page of 30 — 15 participants |
Back to article view | Back to comp.lang.c++
this cast to const char* "Gernot Frisch" <me@privacy.net> - 2011-05-05 19:27 +0200
Re: this cast to const char* Kai-Uwe Bux <jkherciueh@gmx.net> - 2011-05-05 19:39 +0200
Re: this cast to const char* "Balog Pal" <pasa@lib.hu> - 2011-05-06 01:11 +0200
Re: this cast to const char* Marcel Müller <news.5.maazl@spamgourmet.org> - 2011-05-06 01:54 +0200
Re: this cast to const char* m0shbear <andrey.vul@gmail.com> - 2011-05-05 17:59 -0700
Re: this cast to const char* James Kanze <james.kanze@gmail.com> - 2011-05-08 07:08 -0700
Re: this cast to const char* m0shbear <andrey.vul@gmail.com> - 2011-05-08 17:03 -0700
Re: this cast to const char* "Balog Pal" <pasa@lib.hu> - 2011-05-06 20:15 +0200
Re: this cast to const char* James Kanze <james.kanze@gmail.com> - 2011-05-08 07:05 -0700
Re: this cast to const char* James Kanze <james.kanze@gmail.com> - 2011-05-08 07:02 -0700
Re: this cast to const char* Felix Bytow <felix.bytow@informatik.tu-chemnitz.de> - 2011-05-05 19:40 +0200
Re: this cast to const char* Öö Tiib <ootiib@hot.ee> - 2011-05-05 10:52 -0700
Re: this cast to const char* Öö Tiib <ootiib@hot.ee> - 2011-05-05 10:44 -0700
Re: this cast to const char* gwowen <gwowen@gmail.com> - 2011-05-05 10:50 -0700
Re: this cast to const char* Öö Tiib <ootiib@hot.ee> - 2011-05-05 10:58 -0700
Re: this cast to const char* "Bo Persson" <bop@gmb.dk> - 2011-05-05 20:21 +0200
Re: this cast to const char* gwowen <gwowen@gmail.com> - 2011-05-05 11:27 -0700
Re: this cast to const char* Öö Tiib <ootiib@hot.ee> - 2011-05-05 11:37 -0700
Re: this cast to const char* gwowen <gwowen@gmail.com> - 2011-05-05 22:28 -0700
Re: this cast to const char* Öö Tiib <ootiib@hot.ee> - 2011-05-06 03:55 -0700
Re: this cast to const char* "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> - 2011-05-06 13:25 +0200
Re: this cast to const char* Öö Tiib <ootiib@hot.ee> - 2011-05-06 06:22 -0700
Re: this cast to const char* Joshua Maurice <joshuamaurice@gmail.com> - 2011-05-05 22:47 -0700
Re: this cast to const char* Goran <goran.pusic@gmail.com> - 2011-05-06 06:59 -0700
Re: this cast to const char* Pete Becker <pete@versatilecoding.com> - 2011-05-06 10:17 -0400
Re: this cast to const char* James Kanze <james.kanze@gmail.com> - 2011-05-08 07:13 -0700
Re: this cast to const char* "Gernot Frisch" <me@privacy.net> - 2011-05-09 10:38 +0200
Re: this cast to const char* Leigh Johnston <leigh@i42.co.uk> - 2011-05-09 13:03 +0100
Re: this cast to const char* Leigh Johnston <leigh@i42.co.uk> - 2011-05-09 17:51 +0100
Re: this cast to const char* Öö Tiib <ootiib@hot.ee> - 2011-05-09 09:40 -0700
Page 2 of 2 — ← Prev page 1 [2]
| From | "Alf P. Steinbach /Usenet" <alf.p.steinbach+usenet@gmail.com> |
|---|---|
| Date | 2011-05-06 13:25 +0200 |
| Message-ID | <iq0l4l$ok7$1@dont-email.me> |
| In reply to | #4768 |
* Öö Tiib, on 06.05.2011 12:55:
> On May 6, 8:28 am, gwowen<gwo...@gmail.com> wrote:
>> On May 5, 7:37 pm, Öö Tiib<oot...@hot.ee> wrote:
>>
>>> 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?
>>
>> The standard doesn't. Every single implementation that is or ever
>> will be in existence does.
>
> Uhh. I never dare to be so absolute about C++ compilers. Here i can
> even provide evidence of opposite with a compiler manufactured by
> CString creators themselves.
>
> <code>
> // WARNING: this is meant as example
> // of really awful coding practices
> #include<iostream>
> #include<cstdio>
>
> struct Pod { int p; };
>
> class DerivedFromPod
> : public Pod // single derived
> {
> public:
> DerivedFromPod() { p=42; d=0; };
> virtual ~DerivedFromPod() {};
> private:
> int d;
> };
>
> int main()
> {
> DerivedFromPod* der = new DerivedFromPod();
> Pod* pod = der; // implicit cast here
>
> std::cout<< "der is at: "<< der
> << " pod is at: "<< pod<< std::endl;
> printf( "ints from der %d, %d \n", *der );
> printf( "ints from pod %d, %d \n", *pod );
> delete der;
> }
> </code>
>
> Compiling it for Win32 MS compiler Visual C++ 0.9 (bundled in VS
> "CString" 2008 Professional)
> Running it produces something like:
>
> der is at: 00356940 pod is at: 00356944
> ints from der 4290588, 42
> ints from pod 42, -242263521
>
> So there we are with your "Every single implementation that is or ever
> will be in existence does".
One of the reasons why one should not reinterpret_cast up or down a class
hierarchy, but use static_cast which adjusts pointer values appropriately.
That said, I think the original discussion had as an implicit assumption that
one would not introduce virtual methods in derived class.
And in that case the compiler would have to be perverse to start changing the
layout. I'm not sure but I think that for C++0x the compiler would have to stop
such practice, if it ever did. I.e., considerations of layout are not inherently
inappropriate, but one needs to be very careful (like, no virtuals).
Cheers,
- Alf
--
blog at <url: http://alfps.wordpress.com>
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2011-05-06 06:22 -0700 |
| Message-ID | <7ec83b98-9241-4195-8911-cf3d444604e5@v8g2000yqb.googlegroups.com> |
| In reply to | #4769 |
On May 6, 2:25 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach +use...@gmail.com> wrote: > > That said, I think the original discussion had as an implicit assumption that > one would not introduce virtual methods in derived class. One should not assume such things implicitly. Exceptional design constraints should be always documented or if possible enforced with static asserts. Otherwise someone maintains the code and breaks it. As result some printf (possibly called in rare conditions) starts to write utter crap or to crash. > And in that case the compiler would have to be perverse to start changing the > layout. I'm not sure but I think that for C++0x the compiler would have to stop > such practice, if it ever did. I.e., considerations of layout are not inherently > inappropriate, but one needs to be very careful (like, no virtuals). I think that such "undefined behavior" that works predictably and predictability is portable can be documented by standard. I have no real need for it since i avoid using the UB anyway but someone may benefit from it. For example if the location of some hidden and undocumented 'vtable const&' members is anyway similar on most major implementations then why not to document some std::vtable<T> const& as a real implicit member of every class that has virtual functions? If then also to specify the memory layout of a T& (that is internally a T* const anyway on most implementations) then every class would be layout compatible as a result. Like i said i don't need to dig in there and would object someone really using such deep internals but some people (who want to implement reflection for example) might benefit. It does not anyway justify usage of the structured objects as arguments for a printf that is quite awful (confusing and error-prone) practice.
[toc] | [prev] | [next] | [standalone]
| From | Joshua Maurice <joshuamaurice@gmail.com> |
|---|---|
| Date | 2011-05-05 22:47 -0700 |
| Message-ID | <d53aadd6-6420-4988-8058-01ae717dc234@r33g2000prh.googlegroups.com> |
| In reply to | #4726 |
On May 5, 10:27 am, "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.
>
> How does MS doe this?
I just thought I'd pipe in that my own company has done this as well
with its own custom string class, hacked it just like CString so it
works in printf. I hate it. The code will test and work on windows,
but blow up as soon as it's tried on a non-windows platform, and as
most developers are windows based, including myself, this is quite
annoying. I wish they never had a cast operator in their string class,
and I wish they didn't use C-vararg printf style functions. But they
do, and I suffer. Heed the warnings from this thread.
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-05-06 06:59 -0700 |
| Message-ID | <763ee119-dff9-40a9-9c70-69708aa13a65@18g2000prd.googlegroups.com> |
| In reply to | #4726 |
On May 5, 7: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.
>
> How does MS doe this?
Luck (well, cheating). First of all, as said, passing non-pod is UB.
What actually happens is that your string is passed to printf as a
POD. But CString class is made in such a way that "this" is also a
pointer to the first character (there's more to CString than a
pointer, and you don't want to know that ;-).
So... Your code has an error, but you don't see it. To make code error-
free, do:
printf("%s", static_cast<LPCTSTR>(yourstring)));
Or, to avoid casting-induced eyesore, apply some simple DRY:
inline LPCTSTR chars(const CString& s) { return s; }
and then
printf("%s", chars(yourstring));
Had you compiled for Unicode, your code would have not worked. With
Unicode on windows, use _tprintf.
Finally, the only way to trick printf with your type is the trick MS
used. DONT DO THAT! ;-)
Goran.
[toc] | [prev] | [next] | [standalone]
| From | Pete Becker <pete@versatilecoding.com> |
|---|---|
| Date | 2011-05-06 10:17 -0400 |
| Message-ID | <201105061017516095-pete@versatilecodingcom> |
| In reply to | #4776 |
On 2011-05-06 09:59:31 -0400, Goran said:
> On May 5, 7: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.
>>
>> How does MS doe this?
>
> Luck (well, cheating). First of all, as said, passing non-pod is UB.
> What actually happens is that your string is passed to printf as a
> POD. But CString class is made in such a way that "this" is also a
> pointer to the first character (there's more to CString than a
> pointer, and you don't want to know that ;-).
>
> So... Your code has an error,
No, it doesn't. "Undefined behavior" means only that the C++ standard
doesn't tell you what the code does. There's nothing preventing a
compiler from defining the behavior, and there's nothing inherently
wrong with relying on implementation-specific behavior.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)
[toc] | [prev] | [next] | [standalone]
| From | James Kanze <james.kanze@gmail.com> |
|---|---|
| Date | 2011-05-08 07:13 -0700 |
| Message-ID | <f4331d37-e147-4f62-93af-4bd91d7c5129@a18g2000yqj.googlegroups.com> |
| In reply to | #4777 |
On May 6, 3:17 pm, Pete Becker <p...@versatilecoding.com> wrote: > On 2011-05-06 09:59:31 -0400, Goran said: > >> I have the member >const TCHAR* m_data;< as the first member of my string > >> class. > >> How does MS doe this? > > Luck (well, cheating). First of all, as said, passing non-pod is UB. > > What actually happens is that your string is passed to printf as a > > POD. But CString class is made in such a way that "this" is also a > > pointer to the first character (there's more to CString than a > > pointer, and you don't want to know that ;-). > > So... Your code has an error, > No, it doesn't. "Undefined behavior" means only that the C++ standard > doesn't tell you what the code does. There's nothing preventing a > compiler from defining the behavior, and there's nothing inherently > wrong with relying on implementation-specific behavior. And if you're using CString (instead of std::string), you're already very implementation specific, so you might as well take the good (assuming you consider being able to use printf good) with the bad. -- James Kanze
[toc] | [prev] | [next] | [standalone]
| From | "Gernot Frisch" <me@privacy.net> |
|---|---|
| Date | 2011-05-09 10:38 +0200 |
| Message-ID | <92pnfkFtb8U1@mid.individual.net> |
| In reply to | #4776 |
> with "MFC" I can do:
> CString str(_T("test"); printf("%s", str); // prints "test"
Hi,
problem is: We want to replace CString in an existing project, and there are
lots of the above situations.
Now, My string class does not have any virtual member functions. What else
could it be? I can't find how MS did that trick.
Bye,
-Gernot
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2011-05-09 13:03 +0100 |
| Message-ID | <OJydnSAd8MGURVrQnZ2dnUVZ7oWdnZ2d@giganews.com> |
| In reply to | #4828 |
On 09/05/2011 09:38, Gernot Frisch wrote:
>
>
>> with "MFC" I can do:
>> CString str(_T("test"); printf("%s", str); // prints "test"
>
> Hi,
>
> problem is: We want to replace CString in an existing project, and there
> are lots of the above situations.
>
> Now, My string class does not have any virtual member functions. What
> else could it be? I can't find how MS did that trick.
>
> Bye,
> -Gernot
The solution is to do things properly rather than rely on undefined
behaviour as Microsoft are doing:
printf("%s", static_cast<const char*>(yourStringObject)); // provide a
const char* conversion operator in your string class.
Even better would be to stop using the old fashioned printf all together. :)
/Leigh
[toc] | [prev] | [next] | [standalone]
| From | Leigh Johnston <leigh@i42.co.uk> |
|---|---|
| Date | 2011-05-09 17:51 +0100 |
| Message-ID | <K9idnZTVmtsLhlXQnZ2dnUVZ8mudnZ2d@giganews.com> |
| In reply to | #4832 |
On 09/05/2011 13:03, Leigh Johnston wrote:
> On 09/05/2011 09:38, Gernot Frisch wrote:
>>
>>
>>> with "MFC" I can do:
>>> CString str(_T("test"); printf("%s", str); // prints "test"
>>
>> Hi,
>>
>> problem is: We want to replace CString in an existing project, and there
>> are lots of the above situations.
>>
>> Now, My string class does not have any virtual member functions. What
>> else could it be? I can't find how MS did that trick.
>>
>> Bye,
>> -Gernot
>
> The solution is to do things properly rather than rely on undefined
> behaviour as Microsoft are doing:
>
> printf("%s", static_cast<const char*>(yourStringObject)); // provide a
> const char* conversion operator in your string class.
>
> Even better would be to stop using the old fashioned printf all
> together. :)
Actually Öö Tiib is right: adding a c_str() member function is
preferable to my slightly ugly conversion operator suggestion.
/Leigh
[toc] | [prev] | [next] | [standalone]
| From | Öö Tiib <ootiib@hot.ee> |
|---|---|
| Date | 2011-05-09 09:40 -0700 |
| Message-ID | <c9e069f3-b039-4ec0-aeaa-64c89501af54@k22g2000yqh.googlegroups.com> |
| In reply to | #4828 |
On May 9, 11:38 am, "Gernot Frisch" <m...@privacy.net> wrote:
> > with "MFC" I can do:
> > CString str(_T("test"); printf("%s", str); // prints "test"
>
> Hi,
>
> problem is: We want to replace CString in an existing project, and there are
> lots of the above situations.
Can't you just add member 'char const* c_str()' to your string?
Then
CString str(_T("test")); printf("%s", str);
becomes
YourString str("test"); printf("%s", str.c_str());
If it is hard to find the places where to add that '.c_str()' then
download g++ and try to compile , it will warn such places.
> Now, My string class does not have any virtual member functions. What else
> could it be? I can't find how MS did that trick.
MS CString is seemingly header-only. How can it be that you can not
find it? If you can't understand the trick then ... do not use evil
magic you can't understand.
[toc] | [prev] | [standalone]
Page 2 of 2 — ← Prev page 1 [2]
Back to top | Article view | comp.lang.c++
csiph-web