Re: [Edoc-main] Skip throw() function pointers?
Status: Beta
Brought to you by:
bjcosta
From: Niko R. <nr...@mb...> - 2007-12-16 16:17:13
|
On Tue, 2007-12-11 at 14:35 +1100, Brendon Costa wrote: > The only thing that filters out (sinks) a "..." exception type is a > catch(...) All other catch handlers are considered to MAYBE catch this > exception, but they can never sink it. There was a plan to store for > each "..." exception a list of types that wont be rethrown, but that > is not implemented and last time i thought through the consequences of > doing so it started to make my head hurt. So i left it in the too hard > basket. Ignore this part if you want to. I'm failing to understand why EDoc++ works like it does with the simplest of test programs: void f() { try { throw; } catch (int) { } } int main() { try { throw 0; } catch (int) { f(); } } Here, EDoc++ issues a WUNUSED_CATCH about the catch block in f. With the quoted explanation (about "MAYBE catching"), I don't see why. It also tells me int may propagate out of main, but that's to be expected when exceptions out of f is approximated to "...", without excluding int. > > storing the joint lists of emitted exceptions for function classes > > I will look into it more later. For the normal case though this will > use more memory and have very little gain in speed. Not that much more memory. The set of exceptions for every function is already stored. Also storing the union for the class isn't much more, considering that every function only belongs to one class and functions only called directly don't need class information. Obviously the speedup is dependent on the size of the classes. Importantly, how many functions with identical signature are used through function pointers. Not really knowing the code or having done any profiling, it's hard to say how much time is generally spent in gathering exception sets from called functions. Anyway, this probably is far from the most important optimization, it's just the only one I could think of in the context. > That iterative approach might just work quite well! Start with a > complete union and iterate until nothing changes or some maximum > value... It certainly is worth looking into and I think it will be > much faster than the current method. I would still very much prefer it without the union, getting the exact result with the drawback of having to execute the algorithm to completion in order to avoid false negatives. Ideally, implement both, so that the user can choose the union method if the unoptimized exact one is too slow. It wouldn't probably even take many lines of extra code on top of a union + iteration implementation, just start with empty sets instead of the union. It's too easy to think of programs where two functions get a long list of bogus exceptions from the union, and keep passing them to each other. > > By adding exception specifications to the function pointers > > themselves, the list of functions possibly referenced by a given > > function pointer could be reduced > > This is possible, and a much smaller task than monitoring assignment > of function pointers and where they are passed to. A better option > that unfortunatly will require a slight modification to the users code > is to name all the functions of a particular group with a certain > naming convention. E.g.: [...] > In the above if Type1 functions can only be assigned to t1 and Type2 > functions to t2. Then a very simple suppression could be written in a > couple of lines by matching in the start of the function names. This sounds good enough. Either more or less work for the user depending on the program, clearer code with typedefs, and no need to know the possible exceptions. Unfortunately, this leaves the user the responsibility of avoiding an equivalent of "t2 = Type1DoStuff1;", whereas the compiler should automatically check the exception specifications. However, the exception specification approach just lost a lot of its appeal: It seems that currently GCC (at least a not-so-current 4.1.1) actually does not check exception specs in any way in function pointer assignment. Funny enough, it does check them in overriding virtual functions. -- Niko Ritari |