Aaron W. LaFramboise wrote:
> Jason Merrill wrote:
>> Sergio Giro wrote:
>>> I perceived that many people think that the throw qualifiers, as
>>> described by the standard, are not useful
>>
>> Yes.  But that's not a reason to add a slightly different non-standard
>> feature that would require people already using standard exception
>> specifications to rewrite everything.  That's just a non-starter.
> 
> This is also the feature I'd like to see: a static checker for the
> existing throw specification feature.
> 

Thats what EDoc++ ( http://edoc.sourceforge.net/intro.html ) achieves
among a few other things like generating doxygen documentation. However
i agree with Sergio that having a feature that performs static analysis
of exception propagation at compile time as part of GCC would be a
helpful feature.

The problem with EDoc++ as pointed out by Sergio is that it is not
integrated into GCC and so maintainence is an issue as gcc evolves.


> I've been an advocate for eh specs, and I believe they are usable in
> their present form.  For reasons pointed out elsewhere, Java-esque
> static checking really isn't going to work for C++.  The only way that
> Java even gets away with it is why letting the vast majority of
> exceptions--those are derived from Error--slip through.  That is, Java
> throw(something) is equivalent to C++ throw(something, Error), where
> Java's Error is probably close to C++'s std::runtime_error.
> (Unfortunately std::bad_alloc and similar don't derive from
> std::runtime_error or share a common parent.)
> 

EDoc++ provides the ability to "ignore" certain exceptions. The
exception types to ignore can be specified in a "suppressions" file. Its
the users decision as to whether they wish to do this or not.

In my projects using EDoc++ i have opted for NOT including exception
specifiers for all my functions but just using the generated
documentation to determine what exceptions may be thrown. Otherwise as
you said, it will become necessary to include a number of different
std::... exceptions in the throw specifiers for completeness or to
ignore the fact that they may occur. Which brings up the question is it
allowable to let the program terminate if say a std::bad_alloc exception
is thrown.

I think the current manual audit process for using exceptions and
knowing exactly what is going on is the biggest killer for using
exceptions properly in C++. That was the initial purpose of creating
this project.


> The main problem with eh specs in their present form, besides poor
> support on some non-GCC compilers, is the lack of tools available to
> audit the specs.  This is a challenge to implement, as it needs to use
> non-intrusive decorators and heuristics to allow the user to indicate
> cases where exceptions logically won't propagate, even though they
> 'theoretically could.'  Complete static checking would end up being the
> equivalent of -Weffc++: completely useless.
> 

Yes. I agree completely. My first version of EDoc++ did not include the
concept of suppressions, and it just became infeasible to use. There was
too much information and a lot of it just really was not important to
the average developer.

Practically every function that included a throw specifier would emit
errors if it used anything from STL as for example std::bad_alloc would
be thrown or something similar. By using an external suppressions file
it is possible to indicate locations where exceptions will not logically
propagate even though the compiler thinks that they will as well as
saying that std::bad_alloc among others are "runtime" exceptions
equivalent to Java and not necessary in the specs.

Again there are issues involved with maintaining an external
suppressions file as opposed to some form of markup within the source code.

Suppressions can also be used to say i am only interested in information
for a certain set of functions or to restrict the callgraph that may
have been pessimistically expanded from virtual functions or function
pointer calls, or to add function calls (which is currently necessary
when using plugins) or really to modify the resulting data in any way
imaginable. (The suppressions file is actually a python script that can
manipulate the EDoc++ applications internal data structures)

> But I do think the compiler is the right place to do this sort of
> checking, as it needs to have available to it all of the same sorts of
> analysis as a compiler.  Good luck, Sergio, if you want to work on this.
> 

Yes. Trying to construct accurate callgraphs is very difficult without
the compiler. Especially with all the implicitly generated constructors
and the like. Not to mention other issues that i have encountered like
static/inline functions with the same name but DIFFERENT implementations
in different translation units (Jee that is a poor coding style but it
is possible using the preprocessor) and code compiled with
-fno-exceptions linked with code that allows exceptions, same with C++
and C code intermixed, templates and vague linkage, differing throws()
specifiers for a functions prototype in different translation units, and
the list of complexities goes on...

Many issues i believe relate to poor usage of the C++ language or
overlooked bugs caused by things like declaring prototypes in more than
one place and forgetting to copy across the throw() specifier. But all
these wonderful things are "possible" with C++. By generating the
information with the compiler you know exactly what is being used and it
does a lot of the hard work for you.

EDoc++ is implemented as a modification to the gcc 4.0.1 and also
requires a post processing tool that looks at the information generated
by this modified GCC once all the compilation is complete.

To make such a feature as Segio is describing useful in g++, i would say
that the first stage is to get it working as described in previous
emails where it would emit errors for throw specifiers that do not
include say std::bad_alloc, and then as a second stage using some form
of markup in the source or some other method like the external
suppressions file that it should then be capable of modifying that data
to suppress certain exception types, or override compiler generated
information for cases where it can not accurately determine say the
callgraph.

There is a lot of work required in implementing a feature like this well
i think. I do also think however that it is worth the effort (Which is
why i have been working on EDoc++) and that such a feature would be
valuable within gcc itself.

Anyhow, i think i have been rambling again... I am curios to see where
this thread leads.

Brendon.

Reply via email to