On Wed, Mar 07, 2018 at 12:28:57PM +0100, Christophe de Dinechin wrote: > > This behaviour seems inconsistent with std::runtime_error(const char *) > > which as far as I can tell does not have this lifetime expectation. > > You are correct, but please note that std::runtime_error takes a string as input argument, making it very clear that you are dealing with a ‘string’ underneath, not a const char*. Nope, it accepts both in c++11 http://www.cplusplus.com/reference/stdexcept/runtime_error/ And the const char * version will make a copy of the const char * you give it... > > > > >> > >> Anyway, your example is misleading. Anybody that passes the result of > >> string::c_str() to a const char * without proper consideration for the > >> lifetime is at fault. The const char * interface itself cannot be > >> faulted for that. > > > > For what it's worth, I usually expect const char * interfaces to make > > their own copy of the const char * arg if they need it after they > > return, and I've rarely seen exceptions to this expectation. > > std::vector and all standard library containers? You do a push_back of a const char * in an std::vector<string>, you get a copy. If you do that in an std::vector<const char *>, you don’t. I'd argue templated code is special. > Let me give an example from *our own code*. ConcreteConfigureOption > takes two const char * arguments. Does it make copies? No. Same thing > with the related AddOption method. Anything particularly surprising > there? I don’t think so. Hmm, in my opinion it should make a copy... Given what it's used for, it's highly likely it's going to be used with static strings, so why not. But I really would not use that as a generic example which should be followed throughout the codebase ;) > > If I understood properly, things are designed this way to avoid > > running out of memory while building the exception. I'm definitely > > not in favour of having an error-prone API to handle a very rare > > case which the rest of the code is most likely not going to be able > > to cope with anyway. > > To make this clear, let me elaborate a little on *one* other reason (I > listed a few others), code bloat and runtime cost. Let’s say we want > to store a write error with an errno. The two approaches under > consideration are: > > A. throw WriteError(message, operation, errno); > B. throw std::runtime_error(message + “ in “ + operation + “: “ + strerror(errno)) > > I’ll briefly mention, as a gentle reminder of some of the “other reasons”, that (A) is > 1. shorter to type > 2. easier toi read > 3. less error prone > 4. more likely to guarantee consistent messages No problem with having A as an API, but I don't think achieving A mandates that we don't generate the string at the time the exception is created. This really is what is being discussed at this point. And if we are optimizing exception creation from the start, without any profiling data saying we have to do this, I'd say we are falling into very premature optimizations... So... Can we make the API of our exception classes safer to use as requested multiple time? Thanks, Christophe
Attachment:
signature.asc
Description: PGP signature
_______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel