From: DeMarcus on 8 Feb 2010 04:01 > A compiler *could* offer the static checking of no-throw functions as > an extension, but you will very quickly run into practical problems. > > For example, should the compiler, with the feature enabled, complain > about this function: > > void write_to_log(char* text) throw() > { > FILE* logfile = fopen("/var/log/mylogs", "a"); > > fprintf(logfile, "%s", text); > fclose(logfile); > } > > None of the functions used here have a no-throw specification, so the > compiler must assume they can throw an exception (unless the compiler > has special knowledge about these functions, but then just substitute > simple wrappers from an internal, company-specific library). > You're right, but the solution is actually quite simple. Either you just keep your function as it probably looks today, without throw(), as below. void write_to_log(char* text) { FILE* logfile = fopen("/var/log/mylogs", "a"); fprintf(logfile, "%s", text); fclose(logfile); } Or you explain to the compiler that this is indeed a no-throw function using throw() and try/catch(...) as below. void write_to_log(char* text) throw() { try { FILE* logfile = fopen("/var/log/mylogs", "a"); fprintf(logfile, "%s", text); fclose(logfile); } catch(...) {} } > The only way around that is to change the declaration of *every* > function that is known not to throw any exceptions, which is a > prohibitive amount of work. > I realize that we probably can't change existing libraries, but if we could have an optional static check on no-throw functions, i.e. declared throw(), it would be a start of an opening for better exception safety without affecting those who don't want or aren't able to use it. > {excess quoting deleted --mod} > Bart v Ingen Schenau > > -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: ThosRTanner on 8 Feb 2010 04:00 > For example, should the compiler, with the feature enabled, complain > about this function: > > void write_to_log(char* text) throw() > { > FILE* logfile = fopen("/var/log/mylogs", "a"); > > fprintf(logfile, "%s", text); > fclose(logfile); > > } > > None of the functions used here have a no-throw specification, so the > compiler must assume they can throw an exception (unless the compiler > has special knowledge about these functions, but then just substitute > simple wrappers from an internal, company-specific library). I would sincerely hope none of those functions could throw, because they're all C standard library functions, and would cause serious problems if they threw. Any compiler should be able to safely assume that extern "C" functions are nothrow (and that includes when it is compiling one) Moreover, your suggestion is a bit like the objection to const. Once you start putting in const at the top level you have to fix everything you call to be const correct. It's one of those bullets that needs to be bitten. Considering the alternative is that your code will commit suicide at runtime if you get this wrong. And for some of us, that is not an option. As far as they affect us, exception specifications are not only useless, they are extremely dangerous. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: DeMarcus on 8 Feb 2010 11:07 > BTW, as you say, you'd like an optional compiler feature. I don't > think standard deals with such things - they define a language in > "shall" and "shall not" terms. So a compiler could do that, as a > quality of implementation enhancement, not the language (I could be > wrong). Due to perf penalty of throw(), I bet you your proposal would > end in some other mechanics, not "throw()". Perhaps some sort of a > compiler-specific feature (e.g. through __declspec). > Exactly! That's the beauty of it; the standard does *not* need to be touched. Not even the libraries have to be touched! The only thing I'm asking for is an optional feature in the compiler that warns me if a function, declared throw(), contains any function not declaring throw(). That's it! The rest I can do myself. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: peter koch larsen on 8 Feb 2010 11:06 On 8 Feb., 14:36, "Martin B." <0xCDCDC...(a)gmx.at> wrote: > DeMarcus wrote: [snip] > > Nevertheless, just because they're renowned C++ experts, that doesn't > > stop me from proposing enhancements to their ideas. > > > So if the following holds: > > > * A no-throw function can, without functional harm, be declared throw() > > since such function must throw nothing, compared to a throw( MyException > > ) that can throw more than just MyException due to templates. > > If throw() is enforced during runtime - i.e. there is an implicit > catch(...)+handler added to each such function - this can have > performance implications depending on the platform. I assume that you mean "depending on the compiler", not the platform. And this is true, but then complain to the compiler writers or choose a compiler where this overhead is not present. > > > If that holds, then I claim an optional feature in the compiler can, by > > means of static checking during compile-time, help finding no-throw > > functions that throws anyway. This optional feature would be no > > disadvantage, but only an enhancement helping programmers writing > > exception safe code. > > > Please give your comments on this. > > I fully agree that some mechanism to statically enforce/analyse the > no-throw guarantee would be very welcome! The problem is one of technology. With the linking model we use now, it is impossible. And changing the model does not really change anything. Determining if a function can throw is to the best of my knowledge not possible, and if it is, surely it will be computationally to expensive to be usable. Just take a simple function like: std::vector<int> f() { std::vector<int> res(200000); return res; } You can't determine if that function might throw unless you know what new_handler is installed. /Peter -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: DeMarcus on 8 Feb 2010 11:07
> Moreover, your suggestion is a bit like the objection to const. Once > you start putting in const at the top level you have to fix everything > you call to be const correct. It's one of those bullets that needs to > be bitten. Considering the alternative is that your code will commit > suicide at runtime if you get this wrong. And for some of us, that is > not an option. As far as they affect us, exception specifications are > not only useless, they are extremely dangerous. > I don't know what's more dangerous; A) A function that throws even though it gives no-throw guarantee. B) Programmers thinking they've created a no-throw function, when it actually contains functions that can throw. What I mean is that exception specifications may be dangerous, yes, but there is an exception; the no-throw exception specification throw(). Maybe I should clarify that the standard does *not* need to be touched. Not even the libraries have to be touched! The only thing I'm asking for is an optional feature in the compiler that warns me if a function, declared throw(), contains any function not declaring throw(). That's it! The rest I can do myself. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ] |