|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 |
|
Messages: n/a
Hébergeur: |
Previously I've suggested permitting some modification to the
default behaviour wrt to exceptions thrown in a constructor. http://preview.tinyurl.com/278u77 My guess is the default behaviour was decided when networking was less prevalent and should be reconsidered now. I'm not sure if the syntax/mechanism I suggested is good. If you have class Base { ...}; class Inter : public Base { ...}; class Derived : public Inter { ... }; and Base* b = new (preserve) Derived(...); and an exception comes from Derived's constructor, b would be set to the Inter object since that much was built successfully. I'm not sure if/how the syntax would fit in with placement new. The rationale for preserving a base object is because the sender, network and receiver have invested quite a bit in getting to the point of having an Inter. Throwing everything away doesn't make sense to me. Brian Wood Ebenezer Enterprises www.webebenezer.net |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
On Dec 24, 3:45 pm, c...@mailvault.com wrote:
> Previously I've suggested permitting some modification to the > default behaviour wrt to exceptions thrown in a constructor. > > http://preview.tinyurl.com/278u77 > > My guess is the default behaviour was decided when networking > was less prevalent and should be reconsidered now. > > I'm not sure if the syntax/mechanism I suggested is good. > > If you have > > class Base { ...}; > class Inter : public Base { ...}; > class Derived : public Inter { ... }; > > and > > Base* b = new (preserve) Derived(...); > > and an exception comes from Derived's constructor, b would be > set to the Inter object since that much was built successfully. > > I'm not sure if/how the syntax would fit in with placement new. > > The rationale for preserving a base object is because the sender, > network and receiver have invested quite a bit in getting to the > point of having an Inter. Throwing everything away doesn't make > sense to me. > > Brian Wood > Ebenezer Enterpriseswww.webebenezer.net But, what happens to the actual exception? Do the semantics of 'preserve' imply that the exception is eaten and unavailable to the calling code? That would not seem to be very informative as you would most surely still want to have the option of fixing the problem if possible and trying again only the part that failed. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
On 2007-12-24 21:45, coal@mailvault.com wrote:
> Previously I've suggested permitting some modification to the > default behaviour wrt to exceptions thrown in a constructor. > > http://preview.tinyurl.com/278u77 > > My guess is the default behaviour was decided when networking > was less prevalent and should be reconsidered now. > > I'm not sure if the syntax/mechanism I suggested is good. > > If you have > > class Base { ...}; > class Inter : public Base { ...}; > class Derived : public Inter { ... }; > > and > > Base* b = new (preserve) Derived(...); What is wrong with doing it manually, adding new keywords and changing syntax just to make some rare cases does not seem like a very good idea to me. Base* b; try { b = new Derived(...); } catch(SomeException& e) { b = new Inter(...); } -- Erik Wikström |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
On Dec 24, 3:19pm, johanatan <johana...@gmail.com> wrote:
> > But, what happens to the actual exception? Do the semantics of > 'preserve' imply that the exception is eaten and unavailable to the > calling code? I think it would be propagated as usual. The caller could determine if the pointer was to anything useful. > That would not seem to be very informative as you would > most surely still want to have the option of fixing the problem if > possible and trying again only the part that failed. The assumption I'm making is it isn't desirable to have to have large buffers to support retries. One of the things discussed in the thread I mentioned was a maximum message length. The buffers might have to be as big as the max msg length if you don't have something like preserve. I don't think that is the size you would choose for the buffers if they didn't need to be available for retries. Brian Wood Ebenezer Enterprises |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
On Dec 25, 6:09am, Erik Wikström <Erik-wikst...@telia.com> wrote:
> > What is wrong with doing it manually, adding new keywords and changing > syntax just to make some rare cases does not seem like a very good idea > to me. > > Base* b; > try { > b = new Derived(...);} > > catch(SomeException& e) > { > b = new Inter(...); > > } I think it forces you to use inefficient buffer sizes. What you wrote above would work if you have everything needed in a buffer, but it's not as efficient as using something like preserve since the subobjects would be destroyed and then rebuilt. Also, it isn't as flexible; if the hierarchy were Base Inter1 : Base Inter2 : Inter1 Derived : Inter2 you'd have to beef up the above code. What we want is for the system to give the closest object it can to what was requested. You don't know when you write code like the above if things will sometimes mess up in Inter2's construction. In order to get to an Inter1 you would wind up destroying an Inter1 twice and building it three times. (That is assuming the same problem persists between the attempt to build a Derived and an Inter2.) Brian Wood Ebenezer Enterprises |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
On Dec 26, 12:58 am, c...@mailvault.com wrote:
> > But, what happens to the actual exception? Do the semantics of > > 'preserve' imply that the exception is eaten and unavailable to the > > calling code? > > I think it would be propagated as usual. The caller could > determine if the pointer was to anything useful. > > > That would not seem to be very informative as you would > > most surely still want to have the option of fixing the problem if > > possible and trying again only the part that failed. > > The assumption I'm making is it isn't desirable to have to have > large buffers to support retries. One of the things discussed > in the thread I mentioned was a maximum message length. The > buffers might have to be as big as the max msg length if you > don't have something like preserve. I don't think that is the > size you would choose for the buffers if they didn't need to be > available for retries. I don't know enough about what your classes are actually doing (or the inspiration for this thread), but if you are talking about something as specific as buffer sizes as the rationale for a grammar change, then surely there is another way to design this sub-system even within the confines of the current grammar. What about re-ordering the data stream? Let objects be serialized with their most-derived instance data specified first (and thus you would know that all of its ancestors should be able to be constructed). (You could prepend lengths as another idea or in combination with the first). If I'm way off base here, can you give a little more bkg on what exactly these proposed classes are doing? -or- if not, I'd just suggest to 'think outside the box' :-) --there's surely a way to do it without a new 'preserve' mechanism. (Another idea just occurred to me (but less elegant)-- turn your 'is- a' relationships into 'has-a' relationships and let the objs construct each other when needed, if you can't re-order the stream)-- yes, this one's a hack, but it is at least possible. --Jonathan |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
On Dec 28, 2:34 am, johanatan <johana...@gmail.com> wrote:
> On Dec 26, 12:58 am, c...@mailvault.com wrote: > > > The assumption I'm making is it isn't desirable to have to have > > large buffers to support retries. One of the things discussed > > in the thread I mentioned was a maximum message length. The > > buffers might have to be as big as the max msg length if you > > don't have something likepreserve. I don't think that is the > > size you would choose for the buffers if they didn't need to be > > available for retries. > > I don't know enough about what your classes are actually doing (or the > inspiration for this thread), but if you are talking about something > as specific as buffer sizes as the rationale for a grammar change, > then surely there is another way to design this sub-system even within > the confines of the current grammar. I don't have a specific problem here. I agree buffer sizes are specific, but I don't know of a better way than what I suggested. What Erik wrote is an alternative, but I think it has some weaknesses. If the maximum message size were 20 megabytes I think the buffers would have to be that big in order to guarantee support for what he suggested. Buffer sizes aren't the only thing; you also wind up destroying and rebuilding multiple times. I'm not suggesting that the syntax I proposed is how it should be. There may be better ways to handle it. > What about re-ordering the data > stream? Let objects be serialized with their most-derived instance > data specified first (and thus you would know that all of its > ancestors should be able to be constructed). Do you mean default constructed? I guess you're saying something like Derived dv; // default construction serialize into dv A problem with the serialization could still occur. If that happens you're left with a Derived instance in a probably inconsistent state. I would like to have a valid subojbect if I can't get a valid Derived object. Also from that previous thread I mentioned, I'm thinking about there being a stream/serialization constructor... class Derived { public: Derived(handle stream) {} }; Using that is more efficient than default constructing and then serializing. I don't know if anyone is doing that yet. Brian Wood Ebenezer Enterprises |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
On Dec 28, 3:57pm, c...@mailvault.com wrote:
> On Dec 28, 2:34 am, johanatan <johana...@gmail.com> wrote: > > > On Dec 26, 12:58 am, c...@mailvault.com wrote: > > > > The assumption I'm making is it isn't desirable to have to have > > > large buffers to support retries. One of the things discussed > > > in the thread I mentioned was a maximum message length. The > > > buffers might have to be as big as the max msg length if you > > > don't have something likepreserve. I don't think that is the > > > size you would choose for the buffers if they didn't need to be > > > available for retries. > > > I don't know enough about what your classes are actually doing (or the > > inspiration for this thread), but if you are talking about something > > as specific as buffer sizes as the rationale for a grammar change, > > then surely there is another way to design this sub-system even within > > the confines of the current grammar. > > I don't have a specific problem here. I agree buffer sizes > are specific, but I don't know of a better way than what I > suggested. What Erik wrote is an alternative, but I think > it has some weaknesses. If the maximum message size were > 20 megabytes I think the buffers would have to be that big > in order to guarantee support for what he suggested. > Buffer sizes aren't the only thing; you also wind up > destroying and rebuilding multiple times. > > I'm not suggesting that the syntax I proposed is how it > should be. There may be better ways to handle it. > > > What about re-ordering the data > > stream? Let objects be serialized with their most-derived instance > > data specified first (and thus you would know that all of its > > ancestors should be able to be constructed). > > Do you mean default constructed? > I guess you're saying something like > > Derived dv; // default construction > serialize into dv > Well, not necessarily. You could 'peek' into the stream and see prepended useful information so that you could do (in pseudocode): while (stream >> type) { obj o; switch (type) { case derived: o = Derived( stream ); break; case base: o = Base( stream ); break; case ...: ... ... } } In general, always prepend block sizes (if the buffer size is a concern) or the obj type before the actual guts of the obj. > A problem with the serialization could still occur. > If that happens you're left with a Derived instance > in a probably inconsistent state. I would like to > have a valid subojbect if I can't get a valid Derived > object. > Why would a problem occur? Aren't you using TCP/IP? You should be able with modern protocols to be assured at the application level that you receive what was sent. If that isn't true, then you could always invest in a better network stack of some sort (even if it means hand- rolled middleware) to ensure that at the application level this is true. > Also from that previous thread I mentioned, I'm thinking > about there being a stream/serialization constructor... > > class Derived { > public: > Derived(handle stream) {} > > }; > > Using that is more efficient than default constructing > and then serializing. I don't know if anyone is doing > that yet. > See above for example that doesn't use default constructing. Though, the perf difference between default constructing and specialized constructing would be minimal (but if it really matters, I guess it really matters). --Jonathan |
|
![]() |
| Outils de la discussion | |
|
|