From 5102422263042482384
X-Google-Thread: f78e5,3c316a202087bfac
X-Google-Attributes: gidf78e5,public
X-Google-Language: ENGLISH,ASCII-7-bit
Path: g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.speakeasy.net!news.speakeasy.net.POSTED!not-for-mail
NNTP-Posting-Date: Fri, 21 Apr 2006 15:20:08 -0500
Return-Path: <devnull@stump.algebra.com>
X-Spam-Checker-Version: SpamAssassin 3.1.1 (2006-03-10) on ak74.algebra.com
X-Spam-Level: ***
X-Spam-Status: No, score=3.4 required=5.0 tests=HEADER_SPAM,MISSING_HEADERS,
	TO_CC_NONE autolearn=disabled version=3.1.1
X-Authentication-Warning: mulga.cs.mu.OZ.AU: fjh set sender to devnull@stump.algebra.com using -f
X-Robomod: STUMP, ichudov@algebra.com (Igor Chudov)
X-Original-To: std-c++@mailman.ucar.edu
Delivered-To: std-c++@mailman.ucar.edu
Delivered-To: std-c++@ucar.edu
From: "SuperKoko" <tabkannaz@yahoo.fr>
Newsgroups: comp.std.c++
Subject: Re: Defining undefined, etc., behavior
Organization: http://groups.google.com
Message-ID: <1145640678.943315.135690@e56g2000cwe.googlegroups.com>
References: <123m587c3abqge4@corp.supernews.com>
   <S9_%f.69867$dW3.16709@newssvr21.news.prodigy.com>
   <1145261505.465774.326140@z34g2000cwc.googlegroups.com>
   <1145292735.112791.50080@t31g2000cwb.googlegroups.com>
   <1145441229.266883.229800@i39g2000cwa.googlegroups.com>
   <44478375$0$12938$91cee783@newsreader02.highway.telekom.at>
Mime-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
X-Complaints-To: groups-abuse@google.com
User-Agent: G2/0.2
X-HTTP-UserAgent: Mozilla/5.0 (compatible; Konqueror/3.5; Linux) KHTML/3.5.1 (like Gecko),gzip(gfe),gzip(gfe)
Complaints-To: groups-abuse@google.com
Injection-Info: e56g2000cwe.googlegroups.com; posting-host=82.252.147.194;
   posting-account=vOfC2w0AAABzHsIWnglmMRchI1pVxsvC
X-Virus-Scanned: amavisd-new at ucar.edu
X-Virus-Scanned: amavisd-new at cs.mu.OZ.AU
Approved: Fergus Henderson <fjh@cs.mu.oz.au>, moderator of comp.std.c++
X-Virus-Scanned: amavisd-new at cs.mu.OZ.AU
Date: Fri, 21 Apr 2006 15:15:59 CST
Lines: 209
NNTP-Posting-Host: 65.182.171.162
X-Trace: sv3-ttZ2yfuNDgN/4wy+n6sUTnyjQmGGuA4c4HKu3HaTilCvu4hoUEcY7sFuGFKygaBb1ZcFu2OVb8HIMJ1!uOQA96WuwOIPCeFr1KQGi6BnqnUxSXpSejtyasP7iZHyv2Cfx5FcGubEZdFH5PRUQ/78SdnBrnwT!VJpSbbdPm14+Qh9l1OdQVODOmDGENm3mVky7evAZKpU=
X-Complaints-To: abuse@speakeasy.net
X-DMCA-Complaints-To: abuse@speakeasy.net
X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers
X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly
X-Postfilter: 1.3.32
Xref: g2news2.google.com comp.std.c++:1643


Nicolas Pavlidis wrote:

> There is a great problem with exception - spec, and it is named
> templates :-).
>

In fact, even with templates, the notion of "exception-specification" i
gave, remains, is well-defined, and easily checkable by compilers (at
the point of template instanciation)...

However, I agree that it is extremely inconvenient with templates (and
all callbacks mechanisms).

The greater problem is templates, because, in a template definition,
the exception-specification is static (i.e. It can't depend on the
template parameters):

Thus, for example, one could expect std::for_each not to throw when
used with non-throwing operations. But we can't define std::for_each
with a no-throw exception specification, otherwise it would not be
usable with throwing operations...

For templates, there is a solution... Induced exception-specifications.
With a special syntax (or perhaps no special syntax at all), there
should be a mean to say that the compiler must define the exception
specification of the template function, based on operations done inside
the body (basically, that is the union of exceptions that can be thrown
by operations inside the body of the function, except if an exception
is specifically caught with a try/catch block).

With that definition of "induced exception specification", we can
define an exception-specification-correct function as being a function
whose effective exception-specification is looser or equal to the
induced exception-specification.

And, there should be a special syntax (or better, the absence of
explicit exception-specification which is, nowaydays, equivalent to an
exception specification that includes all exceptions in the world)
indicating to the compiler that he must use, as exception-specification
for this function, the induced exception-specification.
That is only possible for templates and inline functions, since the
compiler needs the effective function definition in order to compute
the induced exception-specification.
For non-template, non-inline functions, the compiler would deem that
the induced exception-specification is equal the infinite set of
exceptions.

That would solve the problem of all template containers & functions
that can throw or not, depending on the operations inside them.

So, for example, it would be valid to call std::for_each with
non-throwing operations, in a non-throwing function, without needing
any try/catch block.

That solves most problems, but it does not solve some runtime problems,
such as callbacks:

For instance:
class A
{
public:
void f1() throw();
void f2() const;
};
void Execute10TimesAMember(A&, void (A::*f)())
{
for(unsigned i=0;i<10;++i) a.f();
}

int func() throw()
{
A a;
Execute10TimesAMember(a,&A::f1);
try {
Execute10TimesAMember(a,&A::f2);
Execute10TimesAMember(a,(condition)?&A::f1 : &A::f2); // really
dynamic!
}
catch(...) {
// some code here
}}
Execute10TimesAMember(a,&A::f1) will be deemed as a possibly throwing
function, even if actually
We can't do much against that.
Here are the possibilities :
1) Require the user to provide a try/catch block.
The user, will typically make an assertion failure in the catch
block... Or, recover properly (if it is possible).
2) Allow a special syntax to break the system, with a special
"HeyItReallyCantThrowStupidCompiler" (a better keyword would be chosed)
code block:
int func() throw()
{
A a;
HeyItReallyCantThrowStupidCompiler {
Execute10TimesAMember(a,&A::f1);
}
try {
Execute10TimesAMember(a,&A::f2);
Execute10TimesAMember(a,(condition)?&A::f1 : &A::f2); // really
dynamic!
}
catch(...) {
// some code here
}
}

An exception escaping of a HeyItReallyCantThrowStupidCompiler would
have undefined behaviour.
The main purpose of this syntax is performance...
In fact, since this code will not be too frequent, IMHO, the first
option is better.
3) Allow the HeyItReallyCantThrowStupidCompiler blocks, but catch
runtime exceptions, and use the classical mechanism of reporting
"unexpected exceptions".
IMHO, that's a bad idea, since it has not better performances than
option (1), but add a new keyword, and is less flexible than option
(1), because it is not possible to recover from an unexpected
exception.

That issue with callbacks may seem unacceptable (any form of callbacks,
the C++ style of passing a pointer to an abstract base class as
"callback" as also the problem), but in fact, it is not different from
cv qualifiers problems..

Look at my example:
class A
{
public:
void f1() throw();
void f2() const;
};
void Execute10TimesAMember(A&, void (A::*f)())
{
for(unsigned i=0;i<10;++i) a.f();
}

Sensibly, one could write a function:
void Execute10TimesA_F2(const A& a)
{
Execute10TimesAMember(a, A::f2);
}

But, it does not compile, because of const-correctness.
A const_cast is needed in order to avoid that.

It would be possible explore the possibilities of having cv-qualifiers
template parameters... But that's not the matter here, and I doubt that
it worth the complication.

Conclusion :
Actually, without changing at all the language, a compiler should be
able to check for exception-specification correctness (with the new
definition, where the compiler computes the induced
exception-specification of inline functions and templates at the place
of their instanciation), and generate implicit try/catch blocks, only
where this exception-specification correctness is broken, and emit a
warning at this position.
Like that, instead of constantly being afraid of potential unexpected
exceptions, the programmer would simply be very careful in the seldom
positions where this warning message appears, and probably, add a
try/catch block... at least if the exception is recoverable.

There may be possible to specify that this warning be replaced by an
error, however:
1) Benefits for good programmers that read warning messages, are very
small... Personally, I treat almost identically warning message and an
error messages.
2) Even if that does not change the syntax of the language, it breaks
some code (not much, since there is not much code that uses
exception-specifications other than the infinite-exception-set, and
those programs will still compile).
Nevertheless, it is not a dangerous change : there is no silent
change...
3) It complicates compiler implementations... In fact, for templates,
if definition follows the first instanciation, it is not possible to
implement a single-pass compiler.
That problem already exists with inline functions, since this code is
valid:

inline void f(); //note that the "inline" keyword is required here (see
defect report #317)
void func() {f();}
void f(){}

Another solution, would be to deem that, at the first function usage,
if the definition is not available, the induced exception-specification
is the infinite-set-of-exceptions (and it remains as is, even after the
definition)... but that's so ugly, and I am sure that there are lot of
issues. So... forget it.



But, the question is:
Knowing that benefits are small, does it worth a language change?

IMHO, it should not be a proposal for C++0x...
But this proposal could be proposed to compiler implementers.
I think that it could be included in the GCC compiler (the warning
message could be turned on or off).
That is great for both compiler optimization and program correctness.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]



