Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c++ > #12391 > unrolled thread
| Started by | Andrew Tomazos <andrew@tomazos.com> |
|---|---|
| First post | 2011-12-11 23:57 -0800 |
| Last post | 2011-12-13 10:17 -0800 |
| Articles | 10 — 7 participants |
Back to article view | Back to comp.lang.c++
c_str from anonymous std::string Andrew Tomazos <andrew@tomazos.com> - 2011-12-11 23:57 -0800
Re: c_str from anonymous std::string SG <s.gesemann@gmail.com> - 2011-12-12 00:10 -0800
Re: c_str from anonymous std::string Goran <goran.pusic@gmail.com> - 2011-12-12 00:21 -0800
Re: c_str from anonymous std::string "MikeWhy" <boat042-nospam@yahoo.com> - 2011-12-12 17:39 -0600
Re: c_str from anonymous std::string Tobias Müller <troplin@bluewin.ch> - 2011-12-13 07:13 +0000
Re: c_str from anonymous std::string Juha Nieminen <nospam@thanks.invalid> - 2011-12-13 07:38 +0000
Re: c_str from anonymous std::string Ian Collins <ian-news@hotmail.com> - 2011-12-13 20:49 +1300
Re: c_str from anonymous std::string Andrew Tomazos <andrew@tomazos.com> - 2011-12-13 02:19 -0800
Re: c_str from anonymous std::string "MikeWhy" <boat042-nospam@yahoo.com> - 2011-12-13 11:10 -0600
Re: c_str from anonymous std::string Andrew Tomazos <andrew@tomazos.com> - 2011-12-13 10:17 -0800
| From | Andrew Tomazos <andrew@tomazos.com> |
|---|---|
| Date | 2011-12-11 23:57 -0800 |
| Subject | c_str from anonymous std::string |
| Message-ID | <381e2339-377a-4969-bf8a-7613b811632f@gl2g2000vbb.googlegroups.com> |
class X
{
operator std::string(); // stringify X instance
};
void f(const char*);
X x = ...
f(string(x).c_str());
According to the C++11 standard, will the destructor of std::string be
called before or after the call to f, or is it undefined?
Thanks,
Andrew.
[toc] | [next] | [standalone]
| From | SG <s.gesemann@gmail.com> |
|---|---|
| Date | 2011-12-12 00:10 -0800 |
| Message-ID | <6bcbb7fd-1693-4afa-aa59-68685fb9073d@i6g2000vbh.googlegroups.com> |
| In reply to | #12391 |
On Dec 12, 8:57 am, Andrew Tomazos wrote:
> class X
> {
> operator std::string(); // stringify X instance
> };
>
> void f(const char*);
>
> X x = ...
> f(string(x).c_str());
>
> According to the C++11 standard, will the destructor of std::string be
> called before or after the call to f, or is it undefined?
After. The code is fine.
Cheers!
SG
[toc] | [prev] | [next] | [standalone]
| From | Goran <goran.pusic@gmail.com> |
|---|---|
| Date | 2011-12-12 00:21 -0800 |
| Message-ID | <b919c4e6-cd44-4695-ad09-3e0161de441f@y18g2000yqy.googlegroups.com> |
| In reply to | #12391 |
On Dec 12, 8:57 am, Andrew Tomazos <and...@tomazos.com> wrote:
> class X
> {
> operator std::string(); // stringify X instance
>
> };
>
> void f(const char*);
>
> X x = ...
> f(string(x).c_str());
>
> According to the C++11 standard, will the destructor of std::string be
> called before or after the call to f, or is it undefined?
My understanding is that such temporaries is destroyed when statement
is finished, which, here, is after the semicolon.
Goran.
[toc] | [prev] | [next] | [standalone]
| From | "MikeWhy" <boat042-nospam@yahoo.com> |
|---|---|
| Date | 2011-12-12 17:39 -0600 |
| Message-ID | <jc63b5$3iu$1@dont-email.me> |
| In reply to | #12393 |
Goran wrote:
> On Dec 12, 8:57 am, Andrew Tomazos <and...@tomazos.com> wrote:
>> class X
>> {
>> operator std::string(); // stringify X instance
>>
>> };
>>
>> void f(const char*);
>>
>> X x = ...
>> f(string(x).c_str());
>>
>> According to the C++11 standard, will the destructor of std::string
>> be called before or after the call to f, or is it undefined?
>
> My understanding is that such temporaries is destroyed when statement
> is finished, which, here, is after the semicolon.
It should be further noted that "string(x)" here is an explicit C-style
typecast, syntactically identical to "((std::string)x)", followed by copy
construction of std::string, creating not just one, but *two* temporary
std::string. What a nasty bit of business. This isn't real code, is it? Just
some contrived nastiness to astonish and dismay job applicants?
[toc] | [prev] | [next] | [standalone]
| From | Tobias Müller <troplin@bluewin.ch> |
|---|---|
| Date | 2011-12-13 07:13 +0000 |
| Message-ID | <924584814345451259.474696troplin-bluewin.ch@news.aioe.org> |
| In reply to | #12419 |
"MikeWhy" <boat042-nospam@yahoo.com> wrote:
> It should be further noted that "string(x)" here is an explicit C-style
> typecast, syntactically identical to "((std::string)x)", followed by copy
> construction of std::string, creating not just one, but *two* temporary
> std::string. What a nasty bit of business. This isn't real code, is it?
> Just some contrived nastiness to astonish and dismay job applicants?
Really? Why is operator std::string /followed/ by a copy constuctor? There
is a copy /on returning/ a std::string from the operator function but this
is an inherent "problem" of returning by value and not the fault of the
rest of the code ("problem" in quotes, because this is optimized away by
most compilers).
Or am I misunderstanding something obvious?
Tobi
[toc] | [prev] | [next] | [standalone]
| From | Juha Nieminen <nospam@thanks.invalid> |
|---|---|
| Date | 2011-12-13 07:38 +0000 |
| Message-ID | <4ee70112$0$3122$7b1e8fa0@news.nbl.fi> |
| In reply to | #12419 |
MikeWhy <boat042-nospam@yahoo.com> wrote: > It should be further noted that "string(x)" here is an explicit C-style > typecast, syntactically identical to "((std::string)x)" It looks like a regular object instantiation by calling its constructor to me. (The latter is also interpreted like that.) How else would you construct a temporary object?
[toc] | [prev] | [next] | [standalone]
| From | Ian Collins <ian-news@hotmail.com> |
|---|---|
| Date | 2011-12-13 20:49 +1300 |
| Message-ID | <9koecfFhipU9@mid.individual.net> |
| In reply to | #12419 |
On 12/13/11 12:39 PM, MikeWhy wrote: > > It should be further noted that "string(x)" here is an explicit C-style > typecast, syntactically identical to "((std::string)x)", followed by copy > construction of std::string, creating not just one, but *two* temporary > std::string. In addition to the other corrections, there really isn't such a thing as an "explicit C-style typecast". There is a C style cast (witch is always explicit) and there's a type conversion (which is isn't). -- Ian Collins
[toc] | [prev] | [next] | [standalone]
| From | Andrew Tomazos <andrew@tomazos.com> |
|---|---|
| Date | 2011-12-13 02:19 -0800 |
| Message-ID | <4e7f5148-4ed7-4c9c-9f1d-42ed11124eef@y7g2000vbe.googlegroups.com> |
| In reply to | #12419 |
On Dec 13, 12:39 am, "MikeWhy" <boat042-nos...@yahoo.com> wrote:
> Goran wrote:
> > On Dec 12, 8:57 am, Andrew Tomazos <and...@tomazos.com> wrote:
> >> class X
> >> {
> >> operator std::string(); // stringify X instance
>
> >> };
>
> >> void f(const char*);
>
> >> X x = ...
> >> f(string(x).c_str());
>
> >> According to the C++11 standard, will the destructor of std::string
> >> be called before or after the call to f, or is it undefined?
>
> > My understanding is that such temporaries is destroyed when statement
> > is finished, which, here, is after the semicolon.
>
> It should be further noted that "string(x)" here is an explicit C-style
> typecast, syntactically identical to "((std::string)x)", followed by copy
> construction of std::string, creating not just one, but *two* temporary
> std::string.
$ cat < test.cpp
#include <iostream>
using namespace std;
class A
{
public:
A() { cout << "d"; }
A(const A& a) : x(a.x) { cout << "c"; }
int getx() const { return x; }
int x;
};
class B
{
public:
B(int i) : x(i) {}
operator A() { A a; a.x = x; return a; }
int x;
};
void f(int x) { cout << x << endl; }
int main(int argc, char** argv)
{
B b(argc);
f(A(b).getx());
}
$ g++ test.cpp
$ ./a.out
d1
I only count one d. :)
Due to the return value optimization...
<http://en.wikipedia.org/wiki/Return_value_optimization>
> What a nasty bit of business. This isn't real code, is it? Just
> some contrived nastiness to astonish and dismay job applicants?
Imagine how much less embarrassed you would be if you stated it this
way:
"I think that two temporaries will be created, won't they?"
and left it at that. ;)
Enjoy,
Andrew.
[toc] | [prev] | [next] | [standalone]
| From | "MikeWhy" <boat042-nospam@yahoo.com> |
|---|---|
| Date | 2011-12-13 11:10 -0600 |
| Message-ID | <jc80ue$sfu$1@dont-email.me> |
| In reply to | #12437 |
Andrew Tomazos wrote:
> On Dec 13, 12:39 am, "MikeWhy" <boat042-nos...@yahoo.com> wrote:
>> Goran wrote:
>>> On Dec 12, 8:57 am, Andrew Tomazos <and...@tomazos.com> wrote:
>>>> class X
>>>> {
>>>> operator std::string(); // stringify X instance
>>
>>>> };
>>
>>>> void f(const char*);
>>
>>>> X x = ...
>>>> f(string(x).c_str());
>>
>>>> According to the C++11 standard, will the destructor of std::string
>>>> be called before or after the call to f, or is it undefined?
>>
>>> My understanding is that such temporaries is destroyed when
>>> statement is finished, which, here, is after the semicolon.
>>
>> It should be further noted that "string(x)" here is an explicit
>> C-style typecast, syntactically identical to "((std::string)x)",
>> followed by copy construction of std::string, creating not just one,
>> but *two* temporary std::string.
>
> $ cat < test.cpp
>
> #include <iostream>
>
> using namespace std;
>
> class A
> {
> public:
> A() { cout << "d"; }
> A(const A& a) : x(a.x) { cout << "c"; }
>
> int getx() const { return x; }
> int x;
> };
>
> class B
> {
> public:
> B(int i) : x(i) {}
> operator A() { A a; a.x = x; return a; }
>
> int x;
> };
>
> void f(int x) { cout << x << endl; }
>
> int main(int argc, char** argv)
> {
> B b(argc);
>
> f(A(b).getx());
> }
>
> $ g++ test.cpp
> $ ./a.out
> d1
>
> I only count one d. :)
>
> Due to the return value optimization...
> <http://en.wikipedia.org/wiki/Return_value_optimization>
>
>> What a nasty bit of business. This isn't real code, is it? Just
>> some contrived nastiness to astonish and dismay job applicants?
>
> Imagine how much less embarrassed you would be if you stated it this
> way:
>
> "I think that two temporaries will be created, won't they?"
>
> and left it at that. ;)
>
> Enjoy,
> Andrew.
Cause for my embarrassment is wholly imaginary.
The following produced:
[[
Boo::operator ZooString()const
ZooString<0013FF48>::ZooString(const char *) {Boo}
ZooString<0013FF2C>::ZooString(const ZooString &) {Boo}
Boo
]]
Note the copy construction.
//================================
//================================
#include <iostream>
#include <string>
//================================
//================================
class ZooString
{
public:
ZooString(const char * s = "")
: str(s)
{ PrintTo(std::cout, "::ZooString(const char *)") << '\n';
}
ZooString(const ZooString & r)
: str(r.str)
{ PrintTo(std::cout, "::ZooString(const ZooString &)") << '\n';
}
const char * c_str() const
{
return str.c_str();
}
std::ostream & PrintTo(std::ostream & os, const char * msg) const
{
os << "ZooString<" << (void*)this << '>' << msg
<< " {" << str << '}';
return os;
}
private:
std::string str;
};
//================================
//================================
class Boo
{
public:
Boo(){}
Boo(const Boo &);
operator ZooString() const
{ std::cout << "Boo::operator ZooString()const\n";
return "Boo";
}
};
//================================
//================================
int main(int, char**)
{
Boo hoo;
std::cout << ZooString(hoo).c_str() << '\n';
return 0;
}
[toc] | [prev] | [next] | [standalone]
| From | Andrew Tomazos <andrew@tomazos.com> |
|---|---|
| Date | 2011-12-13 10:17 -0800 |
| Message-ID | <44688b4f-33b3-4a9b-ac9d-086f21a972a7@p14g2000yqp.googlegroups.com> |
| In reply to | #12456 |
On Dec 13, 6:10 pm, "MikeWhy" <boat042-nos...@yahoo.com> wrote:
> Andrew Tomazos wrote:
> > On Dec 13, 12:39 am, "MikeWhy" <boat042-nos...@yahoo.com> wrote:
> >> Goran wrote:
> >>> On Dec 12, 8:57 am, Andrew Tomazos <and...@tomazos.com> wrote:
> >>>> class X
> >>>> {
> >>>> operator std::string(); // stringify X instance
>
> >>>> };
>
> >>>> void f(const char*);
>
> >>>> X x = ...
> >>>> f(string(x).c_str());
>
> >>>> According to the C++11 standard, will the destructor of std::string
> >>>> be called before or after the call to f, or is it undefined?
>
> >>> My understanding is that such temporaries is destroyed when
> >>> statement is finished, which, here, is after the semicolon.
>
> >> It should be further noted that "string(x)" here is an explicit
> >> C-style typecast, syntactically identical to "((std::string)x)",
> >> followed by copy construction of std::string, creating not just one,
> >> but *two* temporary std::string.
>
> > $ cat < test.cpp
>
> > #include <iostream>
>
> > using namespace std;
>
> > class A
> > {
> > public:
> > A() { cout << "d"; }
> > A(const A& a) : x(a.x) { cout << "c"; }
>
> > int getx() const { return x; }
> > int x;
> > };
>
> > class B
> > {
> > public:
> > B(int i) : x(i) {}
> > operator A() { A a; a.x = x; return a; }
>
> > int x;
> > };
>
> > void f(int x) { cout << x << endl; }
>
> > int main(int argc, char** argv)
> > {
> > B b(argc);
>
> > f(A(b).getx());
> > }
>
> > $ g++ test.cpp
> > $ ./a.out
> > d1
>
> > I only count one d. :)
>
> > Due to the return value optimization...
> > <http://en.wikipedia.org/wiki/Return_value_optimization>
>
> >> What a nasty bit of business. This isn't real code, is it? Just
> >> some contrived nastiness to astonish and dismay job applicants?
>
> > Imagine how much less embarrassed you would be if you stated it this
> > way:
>
> > "I think that two temporaries will be created, won't they?"
>
> > and left it at that. ;)
>
> > Enjoy,
> > Andrew.
>
> Cause for my embarrassment is wholly imaginary.
>
> The following produced:
>
> [[
> Boo::operator ZooString()const
> ZooString<0013FF48>::ZooString(const char *) {Boo}
> ZooString<0013FF2C>::ZooString(const ZooString &) {Boo}
> Boo
> ]]
>
> Note the copy construction.
So get a real compiler...
$ g++ YourExample.cpp
$ ./a.out
Boo::operator ZooString()const
ZooString<0x7fff335e93e0>::ZooString(const char *) {Boo}
Boo
$ g++ --version
g++ (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
Regards,
Andrew.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.c++
csiph-web