C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Throwing exception in constructor
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
sunil
Guest





PostPosted: Thu Sep 07, 2006 11:27 pm    Post subject: Throwing exception in constructor Reply with quote



Hi,
A quick question. I am trying to figure out the best way to
communicate error when constructing an object. I have read some
threads that discussed about possible issues when doing that. According
to my research so far, its OK to throw an exception in a constructor,
only thing is that destructor for that class wont be called, so we need
to add code in the classes constructor to free any resources
(memory/files) allocated so far. Is this correct?
Also according to my observations from test programs, the run time
system will call destructor of all the base classes (if the class
rising an exception is a derived class). So can I assume that all the
memory/resources will be freed properly if I just follow one guideline:
In the class throwing exception, make sure to release the resources
allocated thusfar.
Thanks,
Sunil


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Fri Sep 08, 2006 4:56 am    Post subject: Re: Throwing exception in constructor Reply with quote



* sunil:
Quote:
Hi,
A quick question. I am trying to figure out the best way to
communicate error when constructing an object. I have read some
threads that discussed about possible issues when doing that. According
to my research so far, its OK to throw an exception in a constructor,
only thing is that destructor for that class wont be called,

Almost right. It's not just OK to throw an exception to signal a
construction failure. In not-extremely-badly designed code it's
mandatory, to ensure you only ever deal with fully initialized objects,
and no half-way constructed objects (doing the opposite is one way of
streching a 2 to 3 hour programming job into 2 or 3 weeks...).


Quote:
so we need
to add code in the classes constructor to free any resources
(memory/files) allocated so far. Is this correct?

Not in general. Destructors for all successfully constructed
sub-objects are called. That means that if your members are either pure
plain old data (which need no destruction) or objects with destructors
(as they should be, e.g. smart pointers), you're fine without having to
add any cleanup code in the constructor. This is a special case of the
Redundancy Is Evil rule for software. Centralizing cleanup in
destructors is good, duplicating cleanup in constructors is bad.

Of course sometimes it is decidedly overkill to implement a special
purpose class just to encapsulate a resource that needs cleanup.

In such cases consider general smart pointers and scope guards -- and
when you find that, for example, you've managed the same resource with a
scope guard three times, it becomes more attractive to make a class.


Quote:
Also according to my observations from test programs, the run time
system will call destructor of all the base classes (if the class
rising an exception is a derived class). So can I assume that all the
memory/resources will be freed properly if I just follow one guideline:
In the class throwing exception, make sure to release the resources
allocated thusfar.

Well, yes, but the simple way to do that is ... to use objects with
destructors, a.k.a. the C++ RAII idiom.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
AlbertSSj
Guest





PostPosted: Fri Sep 08, 2006 9:14 pm    Post subject: Re: Throwing exception in constructor Reply with quote



sunil wrote:
Quote:
Hi,
that destructor for that class wont be called, so we need
to add code in the classes constructor to free any resources
(memory/files) allocated so far. Is this correct?

You must keep in mind that on a constructor exception only
the fully constructed items will be destructed.

For example:
class foo {
public:
foo() { throw something; }
}

class bar {
private:
std::string a;
std::string* pb;
foo c;
std::string d;
public:
bar() : a("ciao"), b(new std::string("hello")), d("konnichiwa") {}
}

On bar creation what will happen?
Exactly what do you expect

- 'a' will be created completely
- a string will be created and assigned to 'b'
- the exception from foo() will be raised
- d will NOT be constructed
- a will be destructed

In a more complex case you do not known if an exception
is raised before o after 'b', so you cannot delete 'b'.
(You mention a manual managing of the objects,
but isn't always possible)

'b' can be freed in an automatic way simply using a smart pointer,
for example declaring bar as:

class bar {
private:
std::string a;
std::auto_ptr<std::string> pb;
foo c;
std::string d;
public:
bar() : a("ciao"), b(new std::string("hello")), d("konnichiwa") {}
}

A good reference about this cases can be "More Effective C++".


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Maxim Yegorushkin
Guest





PostPosted: Fri Sep 08, 2006 9:17 pm    Post subject: Re: Throwing exception in constructor Reply with quote

Alf P. Steinbach wrote:

[]

Quote:
Of course sometimes it is decidedly overkill to implement a special
purpose class just to encapsulate a resource that needs cleanup.

In such cases consider general smart pointers and scope guards -- and
when you find that, for example, you've managed the same resource with a
scope guard three times, it becomes more attractive to make a class.

In some cases local scope guards may suffice:

struct some
{
some()
{
struct guard {
some* that;
~guard() { if(that) that->close(); }
} guard = { this };

// initialization which may throw

guard.that = 0;
}

~some() { this->close(); }

void close() { /* close/release resources here */ }
};


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Fri Sep 08, 2006 9:19 pm    Post subject: Re: Throwing exception in constructor Reply with quote

Alf P. Steinbach wrote:
Quote:
* sunil:

A quick question. I am trying to figure out the best way to
communicate error when constructing an object. I have read
some threads that discussed about possible issues when
doing that. According to my research so far, its OK to
throw an exception in a constructor, only thing is that
destructor for that class wont be called,

Almost right. It's not just OK to throw an exception to
signal a construction failure. In not-extremely-badly
designed code it's mandatory, to ensure you only ever deal
with fully initialized objects, and no half-way constructed
objects (doing the opposite is one way of streching a 2 to 3
hour programming job into 2 or 3 weeks...).

That's generally the rule. But there are exceptions, and I
wouldn't consider the iostream hierarchy poorly designed because
ifstream doesn't throw if it cannot open the file. Anytime an
object can become invalid during its lifetime (and so later
tests of validity or success are necessary anyway), the argument
based on the absense of invalid objects looses its power.
(Depending on the case, there may be other arguments for
exceptions in such cases. But it's not the cut and dried case
it would be otherwise.)

There are also probably a few rare cases (although I can't think
of any off hand) where it is justified to use a factory
function, which either separates initialization from
construction, or tests the success of the constructor, and in
case of failure, deletes the object and returns a null pointer.

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Fri Sep 08, 2006 11:10 pm    Post subject: Re: Throwing exception in constructor Reply with quote

* kanze:
Quote:
Alf P. Steinbach wrote:
* sunil:
According to my research so far, its OK to
throw an exception in a constructor, only thing is that
destructor for that class wont be called,

Almost right. It's not just OK to throw an exception to
signal a construction failure. In not-extremely-badly
designed code it's mandatory, to ensure you only ever deal
with fully initialized objects, and no half-way constructed
objects (doing the opposite is one way of streching a 2 to 3
hour programming job into 2 or 3 weeks...).

That's generally the rule. But there are exceptions, and I
wouldn't consider the iostream hierarchy poorly designed because
ifstream doesn't throw if it cannot open the file.

Right -- the effects of the poor design shows up in other ways... ;-)


Quote:
Anytime an
object can become invalid during its lifetime (and so later
tests of validity or success are necessary anyway), the argument
based on the absense of invalid objects looses its power.

Just a little. Mostly the argument is against an additional nullstate
(zombie state) /mixed in with other state/, which must be checked
everywhere, leading to complexity (a.k.a. spaghetti) and bugs. As an
example, and this is a special case of a well-known state pattern I
forget the name of, access of an object representing an open file can be
restricted to a special kind of smart-pointer so that the "real" object
doesn't need to deal with the nullstate, except notifying the containing
smart pointer of its further non-existence, and so that the containing
smart pointer only deals with (throwing exceptions on operations on)
nullstate: clean code in both classes, and reusable generic nullstate.

Why isn't it ordinarily done that way?

Well, why am I currently fighting with triple-phase initialization and
other monstrosities? I think there's a very strong tendency to design
and code /locally/ for what the slightly less than average programmer in
the firm/shop/project can be expected to understand and maintain. Then
this seemingly bright idea yields unmaintainable global spaghetti, which
in turn yields local spaghetti, 99.7% contrary to what one aimed for.


Quote:
(Depending on the case, there may be other arguments for
exceptions in such cases. But it's not the cut and dried case
it would be otherwise.)

There are also probably a few rare cases (although I can't think
of any off hand) where it is justified to use a factory
function, which either separates initialization from
construction, or tests the success of the constructor, and in
case of failure, deletes the object and returns a null pointer.

Ah, you're thinking of deserialization... ;-)

At least, I've been thinking about it lately.

There is a conflict there between the initialization order imposed by
C++ and the order very strongly suggested by the serialized data. One
solution is buffering, another and probably both more practical and
efficient solution is to cast the data member declaration order in stone
for serializable objects, and a third is to not regard the serialized
data as a stream, but as random access. Whatever solution one adopts
(and mostly it seems serialization frameworks, including the one in
Boost, choose none of these reasonable options and instead go for ugly
two-phase initialization) there is some trade-off: that's engineering.

Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
James Kanze
Guest





PostPosted: Sun Sep 10, 2006 4:45 pm    Post subject: Re: Throwing exception in constructor Reply with quote

Alf P. Steinbach wrote:
Quote:
* kanze:

[...]
Quote:
Anytime an
object can become invalid during its lifetime (and so later
tests of validity or success are necessary anyway), the argument
based on the absense of invalid objects looses its power.

Just a little. Mostly the argument is against an additional
nullstate (zombie state) /mixed in with other state/, which
must be checked everywhere, leading to complexity (a.k.a.
spaghetti) and bugs.

My point was only that for some object types, this "zombie"
state can come into being after successful construction, so you
need the tests everywhere anyway. In such cases, that one
particular argument in favor of exceptions in constructors is
more or less invalidated. (That doesn't mean that there might
not be others, and if the error condition is exceptional, and
probably cannot be handled locally, an exception might still
very well be in order.)

Quote:
As an example, and this is a special case of a well-known
state pattern I forget the name of, access of an object
representing an open file can be restricted to a special kind
of smart-pointer so that the "real" object doesn't need to
deal with the nullstate, except notifying the containing smart
pointer of its further non-existence, and so that the
containing smart pointer only deals with (throwing exceptions
on operations on) nullstate: clean code in both classes, and
reusable generic nullstate.

Why isn't it ordinarily done that way?

Because that forces the error to be an exception, and most of
the time, you want to handle it locally:-).

Quote:
Well, why am I currently fighting with triple-phase
initialization and other monstrosities? I think there's a
very strong tendency to design and code /locally/ for what the
slightly less than average programmer in the firm/shop/project
can be expected to understand and maintain. Then this
seemingly bright idea yields unmaintainable global spaghetti,
which in turn yields local spaghetti, 99.7% contrary to what
one aimed for.

That's certainly true, at least in general. Trying to make
something simpler than it really is usually ends up resulting in
the complexity getting tacked on later, rather than being
handled in the design. Isn't there a rule: make it as simple as
possible, but no simpler.

Quote:
(Depending on the case, there may be other arguments for
exceptions in such cases. But it's not the cut and dried
case it would be otherwise.)

There are also probably a few rare cases (although I can't
think of any off hand) where it is justified to use a
factory function, which either separates initialization from
construction, or tests the success of the constructor, and
in case of failure, deletes the object and returns a null
pointer.

Ah, you're thinking of deserialization... Wink

Maybe:-). To tell the truth, I wasn't thinking of anything in
particular. I was simply refusing the idea that such cases
couldn't exist.

Quote:
At least, I've been thinking about it lately.

There is a conflict there between the initialization order
imposed by C++ and the order very strongly suggested by the
serialized data. One solution is buffering, another and
probably both more practical and efficient solution is to cast
the data member declaration order in stone for serializable
objects, and a third is to not regard the serialized data as a
stream, but as random access. Whatever solution one adopts
(and mostly it seems serialization frameworks, including the
one in Boost, choose none of these reasonable options and
instead go for ugly two-phase initialization) there is some
trade-off: that's engineering.

That's interesting. In every application I've worked on where
we needed serialization, we've used machine generated code to do
it. This sometimes ends up with a lot of extra classes: the
data declarations are generated by a program, and you derived a
second class to provide the behavior. But it seems to handle
the problem of ensuring that the order of serialization
corresponds to the order of declaration: you only write the
order once, and the program uses it for both serialization and
the declarations.

--
James Kanze (Gabi Software) email: kanze.james (AT) neuf (DOT) fr
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Mon Sep 11, 2006 6:29 pm    Post subject: Re: Throwing exception in constructor Reply with quote

* James Kanze:
Quote:
Alf P. Steinbach wrote:
* kanze:

[...]
Anytime an
object can become invalid during its lifetime (and so later
tests of validity or success are necessary anyway), the argument
based on the absense of invalid objects looses its power.

Just a little. Mostly the argument is against an additional
nullstate (zombie state) /mixed in with other state/, which
must be checked everywhere, leading to complexity (a.k.a.
spaghetti) and bugs.

My point was only that for some object types, this "zombie"
state can come into being after successful construction, so you
need the tests everywhere anyway.

Nope. One way to avoid "tests everywhere" was described in my previous
posting. More detailed explanation below.


Quote:
In such cases, that one
particular argument in favor of exceptions in constructors is
more or less invalidated.

Nope.


Quote:
(That doesn't mean that there might
not be others, and if the error condition is exceptional, and
probably cannot be handled locally, an exception might still
very well be in order.)

As an example, and this is a special case of a well-known
state pattern I forget the name of, access of an object
representing an open file can be restricted to a special kind
of smart-pointer so that the "real" object doesn't need to
deal with the nullstate, except notifying the containing smart
pointer of its further non-existence, and so that the
containing smart pointer only deals with (throwing exceptions
on operations on) nullstate: clean code in both classes, and
reusable generic nullstate.

Why isn't it ordinarily done that way?

Because that forces the error to be an exception, and most of
the time, you want to handle it locally:-).

No, and perhaps.

"No": assume P is a nullstate smart pointer holding a file object F.
This doesn't force the construction fauilure for F to propagate an
exception to client code, which can just check P for nullstate.
However, P guarantees that any attempt to use (features that requires a
successfully constructed) F results in a client code exception.

"Perhaps": I don't really buy the notion that exceptions should not be
used locally. If measurements show that this causes unacceptable
inefficiency, then it might be right to re-design or optimize. Doing so
as a matter of course would IMHO be evil premature optimization.

As an example, the Eiffel language's exception handling construct, a
kind of "loop until success or propagate the exception", is geared
directly towards local exception handling.

C++ makes this a tad more difficult to do in a clean way, but there are
solutions, e.g. the template pattern (I think it was Dave Harris who
came up with that application of the pattern in a discussion years ago;
I had argued for introducing something like Eiffel's feature in C++0x).


[snip]
Quote:
There is a conflict there between the initialization order
imposed by C++ and the order very strongly suggested by the
serialized data. One solution is buffering, another and
probably both more practical and efficient solution is to cast
the data member declaration order in stone for serializable
objects, and a third is to not regard the serialized data as a
stream, but as random access. Whatever solution one adopts
(and mostly it seems serialization frameworks, including the
one in Boost, choose none of these reasonable options and
instead go for ugly two-phase initialization) there is some
trade-off: that's engineering.

That's interesting. In every application I've worked on where
we needed serialization, we've used machine generated code to do
it. This sometimes ends up with a lot of extra classes: the
data declarations are generated by a program, and you derived a
second class to provide the behavior. But it seems to handle
the problem of ensuring that the order of serialization
corresponds to the order of declaration: you only write the
order once, and the program uses it for both serialization and
the declarations.

Yes, code generation à la Java RMIC (Remote Method Invocation Compiler),
or for another example the various CORBA or SOAP tools, is very
convenient. I once considered making a code generator similar to RMIC
for interfacing Java to C++ COM classes; I thought I'd name it COMIC
(COM Invocation Compiler), and that was so cute I actually sat down and
wrote some initial code... :-p But such tools are limited.

The initialization order problem for C++ pops up when the original
object that was saved was of a class different from the class of the
reconstituted object, or when the information was not generated by
serialization of an object. For object-to-object, a requirement of
identical classes is the second of the solutions I mentioned in the
quoted passage above. I do not know why common C++ serialization
frameworks such as the ones in MFC and Boost don't make this
requirement, avoiding two-phase initialization.

A mismatch beteen the serialized data order and the C++ initialization
order can happen in (at least) the two ways mentioned above, with two
subcases for the first, for a total of (at least) three ways:

- The classes have different requirements. E.g., they live in
different programs and in program B you're only interested in a
subset of the information, and want to leverage other base classes.

- The requirements and classes have evolved; we're talking
versioned, backwards-compatible serialization here.

- The data did not originate from serialization of an object.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
bwood
Guest





PostPosted: Tue Sep 12, 2006 1:47 am    Post subject: Re: Throwing exception in constructor Reply with quote

{ please, when replyting to this posting, trim the indirect
quoting even further. thanks. -mod }

Alf P. Steinbach wrote:
Quote:
* James Kanze:
Alf P. Steinbach wrote:
* kanze:

[snip]
There is a conflict there between the initialization order
imposed by C++ and the order very strongly suggested by the
serialized data. One solution is buffering, another and
probably both more practical and efficient solution is to cast
the data member declaration order in stone for serializable
objects, and a third is to not regard the serialized data as a
stream, but as random access. Whatever solution one adopts
(and mostly it seems serialization frameworks, including the
one in Boost, choose none of these reasonable options and
instead go for ugly two-phase initialization) there is some
trade-off: that's engineering.

That's interesting. In every application I've worked on where
we needed serialization, we've used machine generated code to do
it. This sometimes ends up with a lot of extra classes: the
data declarations are generated by a program, and you derived a
second class to provide the behavior. But it seems to handle
the problem of ensuring that the order of serialization
corresponds to the order of declaration: you only write the
order once, and the program uses it for both serialization and
the declarations.

Yes, code generation à la Java RMIC (Remote Method Invocation Compiler),
or for another example the various CORBA or SOAP tools, is very
convenient. I once considered making a code generator similar to RMIC
for interfacing Java to C++ COM classes; I thought I'd name it COMIC
(COM Invocation Compiler), and that was so cute I actually sat down and
wrote some initial code... :-p But such tools are limited.

The initialization order problem for C++ pops up when the original
object that was saved was of a class different from the class of the
reconstituted object, or when the information was not generated by
serialization of an object. For object-to-object, a requirement of
identical classes is the second of the solutions I mentioned in the
quoted passage above. I do not know why common C++ serialization
frameworks such as the ones in MFC and Boost don't make this
requirement, avoiding two-phase initialization.

On a simpler level I think building string objects is similar.
How do you avoid buffering the data and then using the buffer to set
the value? String may have to change to better support this.

Brian Wood

"All things (e.g. a camel's journey through
A needle's eye) are possible it's true.
But picture how the camel feels, squeezed out
In one long bloody thread from tail to snout."

C. S. Lewis


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Tue Sep 12, 2006 6:46 am    Post subject: Re: Throwing exception in constructor Reply with quote

* bwood:
Quote:

On a simpler level I think building string objects is similar.
How do you avoid buffering the data and then using the buffer to set
the value? String may have to change to better support this.

Uh, topic drift...

But OK.

If you know a reasonable upper bound for the final size you can simply
initialize the std::string to that size, and place data right into the
string's buffer. Prior to March this year that was only a dirty
in-practice technique akin to premature optimization, because the
standard didn't guarantee a contigous buffer for std::string. But now
you can (at least, if it's enough for you that current implementations
do and the future standard will guarantee a contigous buffer).

Still, I'd rather see something like Java's division of responsibility
with immutable strings built from mutable string buffers.

That would, I think, play better with future threading support.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Maxim Yegorushkin
Guest





PostPosted: Tue Sep 12, 2006 3:40 pm    Post subject: Re: Throwing exception in constructor Reply with quote

Alf P. Steinbach wrote:

Quote:
If you know a reasonable upper bound for the final size you can simply
initialize the std::string to that size, and place data right into the
string's buffer. Prior to March this year that was only a dirty
in-practice technique akin to premature optimization, because the
standard didn't guarantee a contigous buffer for std::string. But now
you can (at least, if it's enough for you that current implementations
do and the future standard will guarantee a contigous buffer).

Could you post a link to the newly established guarantee please? I
failed to google it.


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Alf P. Steinbach
Guest





PostPosted: Tue Sep 12, 2006 11:25 pm    Post subject: Re: Throwing exception in constructor Reply with quote

* Maxim Yegorushkin:
Quote:
Alf P. Steinbach wrote:

If you know a reasonable upper bound for the final size you can simply
initialize the std::string to that size, and place data right into the
string's buffer. Prior to March this year that was only a dirty
in-practice technique akin to premature optimization, because the
standard didn't guarantee a contigous buffer for std::string. But now
you can (at least, if it's enough for you that current implementations
do and the future standard will guarantee a contigous buffer).

Could you post a link to the newly established guarantee please? I
failed to google it.

<url:
http://groups.google.com/group/comp.lang.c++/msg/03344acea1b070a9>, a
comment by Pete Becker, "As of yesterday's [4th Apr. 2006] Library
Working Group vote, it does".

However, on the other hand, "Subject to approval by the full Standards
Committee tomorrow."

On the third hand, Pete never retracted or amended the statement, so I'm
guessing we'll have to ask him.


CC: Pete Becker.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Pete Becker
Guest





PostPosted: Wed Sep 13, 2006 2:12 am    Post subject: Re: Throwing exception in constructor Reply with quote

{ About whether std::string will guarantee contigous storage. "LWG"
that Pete refers to below means "Library Working Group". The list of
C++ standard library active issues is provided at <url:
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html>. -mod/aps }

kanze wrote:
Quote:

Or did you mean April, when the C++ committee last met? But I
don't see anything in the minutes of the meeting which modified
anything with repect to std::string (except that it would be
more widely used---the committee did adopt a proposal to
overload all functions currently taking a char const* with a
variant taking an std::string const&). I'm not aware of any
proposal to change anything in std::basic_string (but I've not
followed the library proposals too closely, so there could
easily have been one I've missed).


LWG Issue 530.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
bwood
Guest





PostPosted: Wed Sep 13, 2006 4:25 am    Post subject: Re: Throwing exception in constructor Reply with quote

Alf P. Steinbach wrote:
Quote:
* bwood:

On a simpler level I think building string objects is similar.
How do you avoid buffering the data and then using the buffer to set
the value? String may have to change to better support this.

Uh, topic drift...

But OK.

If you know a reasonable upper bound for the final size you can simply
initialize the std::string to that size, and place data right into the
string's buffer. Prior to March this year that was only a dirty
in-practice technique akin to premature optimization, because the
standard didn't guarantee a contigous buffer for std::string. But now
you can (at least, if it's enough for you that current implementations
do and the future standard will guarantee a contigous buffer).


What about using a marshalling/serialization constructor that takes a
stream/descriptor? That might make it easier to handle the possibility
of setting the size but getting interrupted before placing the data in
the string's buffer.

Brian Wood


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
kanze
Guest





PostPosted: Wed Sep 13, 2006 6:49 pm    Post subject: Re: Throwing exception in constructor Reply with quote

Alf P. Steinbach wrote:
Quote:
* Maxim Yegorushkin:
Alf P. Steinbach wrote:

If you know a reasonable upper bound for the final size you
can simply initialize the std::string to that size, and
place data right into the string's buffer. Prior to March
this year that was only a dirty in-practice technique akin
to premature optimization, because the standard didn't
guarantee a contigous buffer for std::string. But now you
can (at least, if it's enough for you that current
implementations do and the future standard will guarantee a
contigous buffer).

Could you post a link to the newly established guarantee
please? I failed to google it.

url:
http://groups.google.com/group/comp.lang.c++/msg/03344acea1b070a9>, a
comment by Pete Becker, "As of yesterday's [4th Apr. 2006] Library
Working Group vote, it does".

However, on the other hand, "Subject to approval by the full
Standards Committee tomorrow."

On the third hand, Pete never retracted or amended the
statement, so I'm guessing we'll have to ask him.

Pete indicated in response to my posting that it was issue 530.
Which is marked as ready in the library issues. On the other
hand, I don't see it in the list of ready issues moved into the
C++0x working paper in the minutes of the April meeting.
(Having gotten to the ready status in the library group, I can't
imagine it not getting into the final standard.)

I wonder, however, if it doesn't leave more issues open for
discussion. The fact that data() returns a char const*, for
example, means that you still can't modify through the pointer
returned by data---you have to use the &array[0] trick necessary
with std::vector as well. (Personally, I thought the fact that
contiguity wasn't required was a feature, and not a bug.) I
wonder if there's still time to write up a proposal to add a
non-const data() function to std::string (and both const and
non-const data() to std::vector)---it just seems a little
cleaner (and in both cases, it could give defined behavior even
when the container is empty).

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.