Topic: Pure no-throw
Author: iaugatwxe@x.com (iaugatwxe)
Date: Sun, 19 Sep 2004 08:21:39 GMT Raw View
>>>I don't know why C++ people hate static exception specs that much.
Yeah, I don't know either!?
I find strange that people don't agree or realize that the exceptions
thrown by a function ARE part of the signature and ARE to be enforced
statically. If you expect a function to throw something and it throws
something else your program is going to break exactly in the same way
that it would do if the return type would not match: a crash.
(No, the unexpected handler does not help at all :-) )
>>Maybe because
>>
>>1. they are impractical for templates, whose exceptional behavior
>> depends on that of functions used in them, which is hard to describe
>> formally in the type system; especially as
>
I don't agree.
If you are trying to instantiate a template function which has got a
throw() declaration in a way that it will eventually call a function
that it throws something (declares to throw), the compiler SHOULD
definitely complain. This is a very important static checking.
But see below for the exact semantic that I propose.
> First, this isn't only true for templates - *any* function which
> which calls functions chosen by the caller of the function
> encounters this issue. Second, the problem is greatly reduced if
> one specificies only throw or nothrow - it's the type lists that
> make it truly awful. And the type lists are the least useful part
> of exception specs.
The correct fix for this kind of situations is to specify the throw
specifications on the type of the function pointer that is expected, and
the one that is passed.
E.g. this would be a function pointer with a throw specification:
int (* funptr) (void) throw(A,B); //This syntax should be
//added in the standard
//
//Both THIS form AND the
//strict form defined below
//should be possible. (funptr can
//be pointing to old or new code)
When you pass this function pointer as a parameter, the compiler should
check that the function type AND the throw specification conforms to
what the receiver expects. Of course if it expects throw (A,B,C) and the
passed function pointer only throws (A,B) it's OK.
So the acceptor could be something like e.g.
float illcallyou(int (*callbackptr) (void) throw(A,B,C)) throw(X,Y)
I propose two more ideas:
(1)
Since changing the current throw specifications might screw up old code,
I propose the addition of the keyword "strict" (for which I'm sure we
can find zillions of more uses later).
A function declared as e.g.:
int fun(char c) throw strict (A,B,C) {...}
would have its body statically checked to throw only those things.
Called functions in its body are also checked for throw strict
specifications in order to ensure this.
If in the body there is a call to a fun2 which has a non-strict throw
specification, or no specification at all, an error message is produced
(something like "strict throw functions cannot call non-strict throw
functions, or functions not declaring throw specifications"). For a
workaround to the error see below.
And,
int fun(char c) throw strict ()
would do the static nothrow spec that many are asking in this thread.
(2)
But the C++ people always want to be able to use optimizations.
And also in some cases you might want to call non-strict throw functions
from strict throw functions (old code?). This should be possible if you
know the implementation of the called code and you are OK with it.
So we should also add this syntax:
//we are in a body
.
. //code here
.
throw strict (A,B)
{
... //code here
fun3(param); //call to: void fun3(SomeParam p) throw(A,B,C)
}
. //more code
The code inside the block is treated as "throw strict(A,B)". The
compiler trusts the programmer about fun3 not throwing C in that
particular case.
Also, an additional semantic would be: if you encapsulate all the body
of your function like this:
void myfunction() throw() //Current meaning of throw() here
{
throw () //nothing before this line
{
...
... //lots of calls to functions without throw specifications
...
} //nothing after this line
}
The compiler would trust you that no exception can be thrown out of the
throw(){ } block so will not put handlers for the unexpected exception
and not even stack unrolling across that. ("throw strict ()" would also
work, in respect to this purpose)
Blocks with throw lists like the following are also an option (note that
it's not strict):
throw (A,B) {...}
but I'm not sure of what benefit they would have with the current
crippled throw semantic
blocks like this
throw strict {...} //note no throw parameter list nor parentheses ( )
in a function with a strict throw declaration, tells the compiler to
PERFORM the static throw checking inside the block, but the functions
(old code) with non-strict throw declarations should be promoted and
considered as if they had a strict throw declaration. (meaning: it's old
code but it's reliable, and we cannot change the signatures now, and we
still want to do static exception checking in the [rest of the] caller).
That is, a function called inside the block which had throw declaration
throw (P,Q,R)
is considered as if it was declared
throw strict (P,Q,R)
Inside such block, a called function without any throw declaration is to
be considered as:
throw strict (...) //It's an ellipsis. Means throw anything.
throw strict (...) in facts should also be possible in a function
declaration. It means: I am strict (so the caller [a strict throwing
caller] doesn't have to put wrapper "throw strict {...}" blocks in order
to call me) but I can throw everything so you might need a catch (...)
everything.
This type of declaration can be used to produce compilable code
quickly (even buggy) with static (strict) exception checking enabled
(but actually doing nothing for now) but no temporary wrapper "throw
strict {...}" blocks inside the code (which would have to be removed later).
In this way you can easily code a hierarchy of callers, all declared
with "throw strict (...)". Once it compiles and it does what you want,
you pick the top level caller and you change the throw declaration from
"throw strict (...)" to "throw strict (A)". The compiler will then
complain about the inner call to a function with "throw strict (...)"
inside the body, so you go and correct this second function too... at
the end all functions will have a correct strict throw specification,
and the compiler will guarantee this!
---
I'll try to condense the concepts here and repeat them all over again
for more clarity:
It should be possible to specify function pointers with throw
specifications. Both non-strict throw specifications and strict throw
specifications should be allowed.
Validity of assignment of such a pointer, passing it to a function as a
parameter etc... should all be checked for match on the throw specs. (*)
Pointers to strict throw functions can be assigned to pointers to
non-strict throw functions if the throw list also matches (that is,
receiver has equal list or superset). reinterpret_cast can be used to
convert unsafely if you really need to.
The meaning of throw() and throw(X,Y,Z) in a function signature is left
as it is now. In the body of a throw() function, if you are sure that
nothing will really be thrown and you want to optimize away the handler
for the unexpected, you wrap the potentially-throwing code in a
throw() {...}
block.
if a function is defined with a throw strict (X,Y,Z) specification, all
explicit throws inside the body are checked for statically matching this
throw requirement. Also all the function calls inside the body of such
functions are checked for their strict throw specification: if they
throw too much and that is not catched, a compile error is reported.
Non-strict throw specifications of called functions are not valid for
this check and in facts shall generate an error message (see above).
strict throw() in a function signature also tells the compiler that in
the body there should be no unexpected handler or full-body-wide stack
unrolling (there can be try/catch blocks inside, which can have stack
unrolling).
strict throw (...) in a function signature means that such function can
throw anything, but it's still a strict declaration as far as the static
exception checking in the callers is concerned.
A block
throw (X,Y,Z) {...}
or
throw strict (X,Y,Z) {...}
tells the compiler to trust the programmer: the code inside such blocks
has such throw or strict-throw semantics.
A block
throw strict {...}
tells the compiler that the called functions inside such block will be
considered as having a strict throw declaration instead of their
non-strict one. Throw type list would not change in this promotion. The
correspondent of absent throw declaration in strict mode is "strict
throw (...)".
(*) Actually at this point I DO say that it's VERY GOOD that the absence
of throw specification was assumed as "throw anything" instead of "throw
nothing" so that a receiver (old code) expecting a function pointer
without throw specifications can still accept a function pointer with a
throw specification.
Any comments?
8643384675C82C49C46EBD9DC720E905E63A0A04
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: apm35@student.open.ac.uk (apm)
Date: Sun, 19 Sep 2004 20:04:07 GMT Raw View
iaugatwxe@x.com (iaugatwxe) wrote in message
> But see below for the exact semantic that I propose.
[proposal snipped]
> Any comments?
Yes, please compare with the proposal for stronger exception checking
I made quite some time ago at
http://www.marlowa.plus.com/publications.html
Regards,
Andrew Marlow
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe@x.com (iaugatwxe)
Date: Mon, 20 Sep 2004 05:03:07 GMT Raw View
apm wrote:
>>Any comments?
>
> Yes, please compare with the proposal for stronger exception checking
> I made quite some time ago at
> http://www.marlowa.plus.com/publications.html
I prefer mine :-)
Your proposal does not address the following problems:
(1) There is no syntax without runtime overhead for telling the compiler
that a certain exception declared in a function being called will not in
facts happen in that situation.
Not having this syntax will force try/catch statements which have
runtime overhead. I understand that allowing this can be dangerous, but
there are cases in which it is appropriate: e.g. you are passing a
Socket class to a function, and that function throws strict
(SocketObjectNotInitialized) and you KNOW that you are initializing the
Socket before passing it: *no change in the callee performed at a later
time* can ever make it throw the SocketObjectNotInitialized, so it's
appropriate to skip it in the caller, and it's not dangerous.
WHOPS! I just spotted a problem with my syntax: my syntax for
suppressing an exception of type C from a function that normally throws
(A,B,C) would be "throw strict (A,B) { code here }" which is VERY
dangerous because if the callee is modified to throw an additional types
(say, D), the compiler is not going to complain! And this is wrong! So
we probably need more a "nothrow strict (C) { code here }" type of
block, which declares that class C will not be thrown. This is safe, as
described above. I'm going to update my proposal right now following up
my previous post.
(2) There is no way to call functions with the old throw specification
even if you are sure that they are correct (like current standard
libraries, CORBA generated code, old well-tested libraries...) which
greatly reduces the usability of the new throw spec or puts a big burden
on the creator of all such libraries for porting everything to the new
spec. My proposal addresses this with "throw strict { code here }" blocks.
(3) the keyword "strict" is likely to be used in the future also for
something else in C++, while the throwonly keyword would be useful only
for that purpose.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe@x.com (iaugatwxe)
Date: Mon, 20 Sep 2004 05:22:44 GMT Raw View
Alf P. Steinbach wrote:
Unreachable code huh? I know how to deal with that!
> #include <cassert>
>
> class none {
> none(); // prevent creation
> public:
> template<class T>
> operator T ()
> {
> assert( false );
volatile int i=0;
if (i==0)
{
> return throw throw throw "";
> //assert( "none::operator T(): should never be executed" );
}
> return *(T*)(0);
> }
> };
Try now!!
You see? Volatile in C++ still has an use after all :-)
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: gi2nospam@mariani.ws (Gianni Mariani)
Date: Mon, 20 Sep 2004 05:26:41 GMT Raw View
iaugatwxe wrote:
>>>> I don't know why C++ people hate static exception specs that much.
>
>
> Yeah, I don't know either!?
>
> I find strange that people don't agree or realize that the exceptions
> thrown by a function ARE part of the signature and ARE to be enforced
> statically. If you expect a function to throw something and it throws
> something else your program is going to break exactly in the same way
> that it would do if the return type would not match: a crash.
> (No, the unexpected handler does not help at all :-) )
>
My issue is not with exceptions as such but more with the implementations.
Debugability of the code is very high on my list of priorities. I have
found that violations of the static exception specs ususally results in
no knowledge of the location of the original throw. I want the debugger
to be stopped at the code where the throw was called that violated the
static exception specs. Without this, it becomes a very difficult task
to figure out what the cause of the problem is.
Maybe I'm missing somthing.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 20 Sep 2004 05:26:45 GMT Raw View
In article <cij0gf015iq@news3.newsguy.com>, iaugatwxe <iaugatwxe@x.com>
writes
>Any comments?
Nice theory but al our experience demonstrates that real world problems
make static enforcement of throw specifications impractical. It is hard
to get even a workable set of rules for static enforcement of throw()
[i.e. throws nothing] though I hope we may yet achieve that.
Were it reasonably possible to have static enforcement of ESs we would
already have lint like tools that diagnosed breaches.
Personally I will be happy if we can get static enforcement of throw()
and remove all other exception specifications from the language.
>
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 20 Sep 2004 05:26:51 GMT Raw View
iaugatwxe@x.com (iaugatwxe) writes:
> I find strange that people don't agree or realize that the exceptions
> thrown by a function ARE part of the signature and ARE to be enforced
> statically. If you expect a function to throw something and it throws
> something else your program is going to break exactly in the same way
> that it would do if the return type would not match: a crash.
> (No, the unexpected handler does not help at all :-) )
No, that is exactly the point: in contrast to return types, it is
trivial to write code that doesn't crash when it gets an exception
type it didn't expect.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe@x.com (iaugatwxe)
Date: Mon, 20 Sep 2004 05:27:03 GMT Raw View
While replying to Andrew I just spotted a problem with my previous proposal.
But first a few small corrections:
I just realized that the standard *does* allow throw specifications on
pointers. Very good. So we just need to add the "throw strict"
specifications to pointers.
Also throw specifications should be allowed in the typedefs of function
pointers. It's not clear to me why the standard currently disallows this.
The current standard also mandates that during derivation of classes, a
virtual function cannot weaken its throw specifications. Very good. This
also was needed for addressing the problem mentioned by llewelly (we
also pass objects as parameters in C++, not only function pointers). We
also should allow that during derivation, a virtual function can pass
from normal throw declaration to a throw strict declaration (but not
vice versa).
Here is the major problem of my previous proposal:
//we are in a body of a function with
//a throw strict(A,B,C) declaration
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe@x.com (iaugatwxe)
Date: Mon, 20 Sep 2004 10:44:01 GMT Raw View
David Abrahams wrote:
> No, that is exactly the point: in contrast to return types, it is
> trivial to write code that doesn't crash when it gets an exception
> type it didn't expect.
Ok maybe I shouldn't have said crash but anyway it doesn't work
correctly. There is not that much difference between a crash and a
program which doesn't work correctly: if it is somewhere near to
mission-critical you are screwed anyway.
The compiler should inform you if a called function has been changed and
now throws more stuff, because this implies new semantics and a new
execution flow through your caller. This isn't happening now.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe@x.com (iaugatwxe)
Date: Mon, 20 Sep 2004 10:44:28 GMT Raw View
Francis Glassborow wrote:
> Nice theory but al our experience demonstrates that real world problems
> make static enforcement of throw specifications impractical.
Java people are doing this all the time and their programs work very
well for this very reason. The compiler tells them if some callee has
changed (more throws) and the caller needs to be updated because there
are new semantics and a new possible flow of execution.
I can understand that it can be bothersome at times, and that's why my
proposal is for an "optional" static checking :-)
I want to reply again:
> Nice theory but al our experience demonstrates that
> real world problems make static enforcement of
> throw specifications impractical.
If you cannot enforce exceptions statically it means that you are taking
shortcuts and skipping the handling of some (maybe unlikely) situations
that anyway can arise sometimes and your program would behave
incorrectly. This sounds like unreliable software, doesn't it?
I'm OK with unreliable software sometimes but we also need a way to
ensure reliability don't we? Gosling (inventor of Java) apropos the
exceptions in java said something like: "I don't care about the time it
takes to create a program that kinda-works: I care only about the time
that it takes to make it work 100%!" Well, I must say that he has a point.
Not every program is mission-critical and sometime we can accept to have
it kinda-buggy if we can cut development time significantly with dynamic
exception specifications, but statically checked exceptions should also
be an option for C++.
> It is hard
> to get even a workable set of rules for static enforcement of throw()
Are you talking about the 15.4/10? Are there other problems?
I don't see problems that my proposal wouldn't address, but maybe I'm
missing something, please tell.
(also pls note that I have already changed the proposal because I have
spotted a problem... DOH!)
Alan Griffiths proposal of
extern "nothrow" { <--- what about ``extern "throw()" { '' ?
#include <unistd.h>
}
which I like, also solves a lot of problems with C functions. In the C++
headers wrappers for C (eg <stdio> for <stdio.h>) we would put the block
by Griffiths and then include the C header.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 20 Sep 2004 13:07:25 GMT Raw View
iaugatwxe@x.com (iaugatwxe) writes:
> David Abrahams wrote:
>> No, that is exactly the point: in contrast to return types, it is
>> trivial to write code that doesn't crash when it gets an exception
>> type it didn't expect.
>
> Ok maybe I shouldn't have said crash but anyway it doesn't work
> correctly. There is not that much difference between a crash and a
> program which doesn't work correctly: if it is somewhere near to
> mission-critical you are screwed anyway.
There are very few applications in which the content of error reports
is mission-critical.
> The compiler should inform you if a called function has been changed
> and now throws more stuff, because this implies new semantics and a
> new execution flow through your caller.
It absolutely does not imply a new execution flow, and it usually
doesn't imply new semantics. It implies new data coming out of the
function. Because of the way exception types are checked
dynamically, the damage can be limited.
That isn't to say I think static exception checking is useless. But
let's not overstate the case.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: stephan.bergmann@sun.com (Stephan Bergmann)
Date: Mon, 20 Sep 2004 15:31:54 GMT Raw View
David Abrahams wrote:
> iaugatwxe@x.com (iaugatwxe) writes:
>
>
>>I find strange that people don't agree or realize that the exceptions
>>thrown by a function ARE part of the signature and ARE to be enforced
>>statically. If you expect a function to throw something and it throws
>>something else your program is going to break exactly in the same way
>>that it would do if the return type would not match: a crash.
>>(No, the unexpected handler does not help at all :-) )
>
>
> No, that is exactly the point: in contrast to return types, it is
> trivial to write code that doesn't crash when it gets an exception
> type it didn't expect.
The following code might well be considered contrieved, but it shows
that code can indeed crash when a function throws exceptions that are
not expected, namely when some outer function attaches certain semantics
to exceptions of that type:
// not expected to throw int:
void f1() {
throw 1;
}
int * p = 0;
// expected to throw an int if it sets p:
void f2(bool b, int * q) {
f1();
if (b) {
p = q;
throw 2;
}
}
void f3(bool b, int * q) {
try {
f2(b, q);
} catch (int) {
*p = 3; // fails as p points to null
}
}
To avoid the crash, f2 would have to wrap the call to f1 in a try-catch
block and not let the thrown int from f1 escape f2. In real-world code,
this might be considered a burden.
-Stephan
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: devnull@octopull.demon.co.uk (Alan Griffiths)
Date: Tue, 21 Sep 2004 01:01:41 GMT Raw View
iaugatwxe@x.com (iaugatwxe) wrote in message news:<cilv4701d5v@news3.newsguy.com>...
> David Abrahams wrote:
> > No, that is exactly the point: in contrast to return types, it is
> > trivial to write code that doesn't crash when it gets an exception
> > type it didn't expect.
>
> Ok maybe I shouldn't have said crash but anyway it doesn't work
> correctly. There is not that much difference between a crash and a
> program which doesn't work correctly: if it is somewhere near to
> mission-critical you are screwed anyway.
Sorry, but you are still not getting it. There are well known
techniques for writing C++ code that do not care about the specific
type of any exception that propagates through it. (This is also
possible in Java, but the techniques seem less well known in that
community.) Such code doesn't "crash" or "work incorrectly" because
it doesn't deal with specific exceptions.
The experience of many developers, including myself, is that this is
the normal case in designs that use C++ exceptions. That is
exceptions are not intended to be handled locally. (In C++ exceptions
do not fulfil the same role as Java's checked exceptions - they are
much closer to RuntimeException.)
> The compiler should inform you if a called function has been changed and
> now throws more stuff, because this implies new semantics and a new
> execution flow through your caller. This isn't happening now.
Not so. The important distinction is between a function that doesn't
throw and one that does - that change can break code and I am keen to
get tool support for dealing with it. (Both in C++ and in Java - as
neither has this at the moment.)
--
Alan Griffiths
http://www.octopull.demon.co.uk/
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe <iaugatwxe@x.com>
Date: Mon, 20 Sep 2004 23:22:06 CST Raw View
[somehow the post was truncated: I'm reposting it]
While replying to Andrew I just spotted a problem with my previous proposal.
But first a few small corrections:
I just realized that the standard *does* allow throw specifications on
pointers. Very good. So we just need to add the "throw strict"
specifications to pointers.
Also throw specifications should be allowed in the typedefs of function
pointers. It's not clear to me why the standard currently disallows this.
The current standard also mandates that during derivation of classes, a
virtual function cannot weaken its throw specifications. Very good. This
also was needed for addressing the problem mentioned by llewelly (we
also pass objects as parameters in C++, not only function pointers). We
also should allow that during derivation, a virtual function can pass
from normal throw declaration to a throw strict declaration (but not
vice versa).
Here is the major problem of my previous proposal:
//we are in a body of a function with
//a throw strict(A,B,C) declaration
.
. //code here
Socket s;
s.Initialize();
throw strict (A,B)
{
func(s); //call to:
//void func(Socket &s) throw strict(A,B,SocketNotInitialized)
}
. //more code
If we do the above to tell the compiler that func will not throw
SocketNotInitialized in that particular situation, we are at risk: if
func is later modified to also throw HostUnreachable, the compiler is
not going to issue any error! This would kill the usefulness of the
proposed static exception checking.
In facts I was using the wrong approach. It's better to tell the
compiler that func will not throw SocketNotInitialized, instead of
telling that it can only throw A and B.
Here are the new nothrow blocks I am proposing instead of the "throw"
and "throw strict" blocks of my previous proposal:
nothrow (nothrow_list) { code here }//e.g. nothrow (A,B) {func(x);}
the programmer guarantees that no exception in the nothrow_list will
escape the block. Can be used in the body of any type of functions:
(a) in the body of a function with strict throw declaration
(b) inside functions with the normal (non-strict) throw declaration
(c) inside functions without any throw declaration
In (a) it's useful to stop the compiler complaining about unhandled
exceptions without adding runtime overhead, in case you are sure such
exceptions will not happen in that particular case.
In (b) it can be used to tell the compiler to optimize away the
unexpected handler. For this to happen two things must hold: (1) the
nothrow_list must be wide enough to cover all the possible thrown
exceptions of the functions called inside the block (their throw or
strict-throw declaration is inspected to check this). (2) The code that
remains outside (function calls and explicit throws) also must not throw
anything.
In (c) it's meaningless but I see no reason for forbidding it either.
nothrow (...) { code here } //it's an ellipsis
Similar to the above one. The programmer guarantees that no exception
will escape the enclosing block.
In (a), combined with a strict promotor block, is the only way to call a
function without any throw specification (e.g. a C function) which you
are sure it won't throw. Other uses are discouraged: use the version
with an explicit nothrow_list .
In (b) provides a more convenient way to optimize away the unexpected
handler. In particular it is needed if you are calling functions without
any throw declaration.
In (c) is as useless as the explicit version :-)
Both versions of the nothrow block do not allow you to call non-strict
throwing functions or functions without throw specifications, from
strict-throw functions. To do that you need the following:
throw strict { code here } //Note: no parentheses ( )
"strict promotor" block. The functions called in the code block which
had a non-strict specification are considered as having strict throw
specifications now. So you can call them from the body of strict-throw
functions. It's useful for calling STL, C functions and other old code
which is trusted to be good and cannot be rewritten.
Called functions which didn't have any throw specification are
considered to be "throw strict (...)" (throw anything, strict specification)
What remains of my previous proposal is still valid:
- declaration syntax for throw strict functions:
ret_type func_name(param_list...) throw strict (typelist|``...'');
Similarly for function pointers.
- Function pointers can be converted automatically from throw strict
specification to throw specification but for the reverse you need
reinterpret_cast.
- throw strict functions don't have an unexpected handler. Their body is
checked statically for handling all the exceptions which are not
declared in the throw strict signature of the current function. If you
know what you are doing you can avoid handling some exceptions using the
nothrow blocks.
- nothrow blocks can also be used to optimize away the unexpected
handler in functions with normal (non-strict) throw declaration. To do
this you have to wrap all the potentially-throwing code, and the
nothrow_list shall be wide enough to cover all the potentially-thrown types.
- a "throw strict" function cannot normally call a function with a
non-strict throw declaration: wrap the call with a "strict promotor"
block to do that. The reverse is ok.
F8E11ABD777A5568A68CC194A20FEABE6E3DAFD4
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: David Abrahams <dave@boost-consulting.com>
Date: Mon, 20 Sep 2004 23:25:25 CST Raw View
iaugatwxe@x.com (iaugatwxe) writes:
> WHOPS! I just spotted a problem with my syntax: my syntax for
> suppressing an exception of type C from a function that normally
> throws (A,B,C) would be "throw strict (A,B) { code here }" which is
> VERY dangerous because if the callee is modified to throw an
> additional types (say, D), the compiler is not going to complain!
> And this is wrong! So we probably need more a "nothrow strict (C) {
> code here }" type of block, which declares that class C will not be
> thrown. This is safe, as described above. I'm going to update my
> proposal right now following up my previous post.
Seems almost as error-prone. What if a new function call that happens
to throw C is added to the block?
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: brangdon@cix.co.uk (Dave Harris)
Date: Mon, 20 Sep 2004 23:25:31 CST Raw View
dave@boost-consulting.com (David Abrahams) wrote (abridged):
> No, that is exactly the point: in contrast to return types, it is
> trivial to write code that doesn't crash when it gets an exception
> type it didn't expect.
Do you mean, it's trivial to write code that expects all types of
exception?
-- Dave Harris, Nottingham, UK
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 21 Sep 2004 13:05:18 GMT Raw View
brangdon@cix.co.uk (Dave Harris) writes:
> dave@boost-consulting.com (David Abrahams) wrote (abridged):
>> No, that is exactly the point: in contrast to return types, it is
>> trivial to write code that doesn't crash when it gets an exception
>> type it didn't expect.
>
> Do you mean, it's trivial to write code that expects all types of
> exception?
That's almost the same thing. I mean to say that it's trivial to
write code where the accuracy of the programmer's expectations (about
which particular exception types may be thrown) don't significantly
affect robustness.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Tue, 21 Sep 2004 17:36:34 GMT Raw View
stephan.bergmann@sun.com (Stephan Bergmann) wrote in message news:<cim2es$cic$1@new-usenet.uk.sun.com>...
> The following code might well be considered contrieved, but it shows
> that code can indeed crash when a function throws exceptions that are
> not expected, namely when some outer function attaches certain semantics
> to exceptions of that type:
>
> // not expected to throw int:
> void f1() {
> throw 1;
> }
>
> int * p = 0;
>
> // expected to throw an int if it sets p:
> void f2(bool b, int * q) {
> f1();
> if (b) {
> p = q;
> throw 2;
> }
> }
>
> void f3(bool b, int * q) {
> try {
> f2(b, q);
> } catch (int) {
> *p = 3; // fails as p points to null
> }
> }
>
> To avoid the crash, f2 would have to wrap the call to f1 in a try-catch
> block and not let the thrown int from f1 escape f2. In real-world code,
> this might be considered a burden.
It's interesting that static checking of thrown exceptions would not
have helped identify the problem in this code. Presumably, the
functions would have been declared
void f1();
void f2(bool b, int * q) throw(int);
void f3(bool b, int * q);
The (hypothetical static checking) compiler would have complained that
f1 was throwing an int type without a corresponding spec. The
programmer adds the appropriate exception spec, and now we have
void f1() throw(int);
void f2(bool b, int * q) throw(int);
void f3(bool b, int * q);
The program now compiles, and then crashes at run time.
Bob
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: belvis@pacbell.net (Bob Bell)
Date: Tue, 21 Sep 2004 17:36:39 GMT Raw View
iaugatwxe@x.com (iaugatwxe) wrote in message news:<cilv4t01d43@news3.newsguy.com>...
> Francis Glassborow wrote:
>
> > Nice theory but al our experience demonstrates that real world problems
> > make static enforcement of throw specifications impractical.
>
> Java people are doing this all the time and their programs work very
> well for this very reason.
-- C++ lets a programmer throw any data type (Java doesn't)
-- C++ has templates (Java doesn't)
These two facts have implications that make reasoning about C++
exception specifications based on what Java can do of limited utility.
Bob
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe@x.com (iaugatwxe)
Date: Tue, 21 Sep 2004 20:17:51 GMT Raw View
Alan Griffiths wrote:
> iaugatwxe@x.com (iaugatwxe) wrote in message news:<cilv4701d5v@news3.newsguy.com>...
>
> Sorry, but you are still not getting it. There are well known
> techniques for writing C++ code that do not care about the specific
> type of any exception that propagates through it.
You mean that basically you only "catch (...)"?
This is the only way that comes to my mind.
All the other ways behave incorrectly and possibly crash if the callee
is later modified to throw additional unforeseen types.
The way of catching (...) can certainly work but... I mean... Are we
sure that we want to lose such an expressive power as the type of the
exception? Why does C++ allow typed exceptions then!? They are just
dangerous. Just throw string or nothing.
Statically typed exceptions as an *optional* feature seems a very good
addition to me for C++.
Also there is another problem with catching (...): you always hit the
first layer of try{}. Sometimes you might want to jump farther.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: iaugatwxe@x.com (iaugatwxe)
Date: Tue, 21 Sep 2004 20:18:01 GMT Raw View
David Abrahams wrote:
> iaugatwxe@x.com (iaugatwxe) writes:
>
>> And this is wrong! So we probably need more a "nothrow strict (C) {
>> code here }" type of block, which declares that class C will not be
>> thrown. This is safe, as described above. I'm going to update my
>> proposal right now following up my previous post.
>
>
> Seems almost as error-prone. What if a new function call that happens
> to throw C is added to the block?
Well, when you are adding a function to the block you have to be
extremely sure that it doesn't throw C, at least in that particular
situation.
Don't disable the static check otherwise! :-)
Sometimes you CAN be sure that it will not throw C, e.g. if C is thrown
for some specific thing not being initialized, when you are sure that
you are initializing it just before the call. In THAT case you can shut
down the compiler static check. But you should do it for *that* specific
exception.
With the previous proposal a "still semantically correct" change to the
callee could screw up your program (*). Now a "semantically wrong"
change to the disable-static-check block itself is needed to screw up
your program... do you see it as much error prone?
(*) for example the developer of the callee was adding one more throw
for an additional error condition which he previously forgot to check.
PS: Also I have found a syntax which doesn't imply new keywords. I'm
modifying my proposal again :)
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hyrosen@mail.com (Hyman Rosen)
Date: Wed, 22 Sep 2004 02:05:57 GMT Raw View
iaugatwxe wrote:
> You mean that basically you only "catch (...)"?
No. You don't catch at all. Catching is for when you
know what to do with an exception.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: devnull@octopull.demon.co.uk (Alan Griffiths)
Date: Wed, 22 Sep 2004 16:23:01 GMT Raw View
iaugatwxe@x.com (iaugatwxe) wrote in message news:<cipt3a01cqo@news2.newsguy.com>...
> Alan Griffiths wrote:
> > iaugatwxe@x.com (iaugatwxe) wrote in message news:<cilv4701d5v@news3.newsguy.com>...
> >
> > Sorry, but you are still not getting it. There are well known
> > techniques for writing C++ code that do not care about the specific
> > type of any exception that propagates through it.
>
> You mean that basically you only "catch (...)"?
..
> Also there is another problem with catching (...): you always hit the
> first layer of try{}. Sometimes you might want to jump farther.
Unlike Java you rarely need try...catch blocks in C++ - and the norm
is for exceptions to propagate through many stack frames. Vis:
http://www.octopull.demon.co.uk/c++/dragons/
http://www.boost.org/more/generic_exception_safety.html
And yes, at the very top of the stack it may be appropriate to catch
(...), but usually, catch (std::exception const& error) is sufficient.
--
Alan Griffiths
http://www.octopull.demon.co.uk/
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly <llewelly.at@xmission.dot.com>
Date: Fri, 3 Sep 2004 04:28:05 GMT Raw View
dave@boost-consulting.com (David Abrahams) writes:
> SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:
>
>> "David Abrahams" <dave@boost-consulting.com> wrote in message
>> news:uzn4dtma4.fsf@boost-consulting.com...
>>> SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website
>>> for Email)") writes:
>>>
>>>> A swap that doesn't throw versus one that throws is the difference
>>>> between a correct and an incorrect function.
>>>
>>> Careful. Some people have set up the expectation that swap shouldn't
>>> throw, but it's by no means a requirement.
>>
>> Not sure I understand. For example, the copy via swap algorithm
>
> "copy via swap algorithm?" Never heard of it.
>
>> is useful iff swap doesn't throw. I guess there are other examples
>> when indeed code could work whether or not swap could throw, but
>> most of the code I write hopes for a nonthrowing (and cheap)
>> swap.
>
> Exactly. There's no standard requirement that your swaps be
> nonthrowing, and there's no a priori reason why swap shouldn't
> throw.
>
>> Would be great if swap's nonthrowingness would be verified
>> statically...
Several of the standard swaps - like vector<T>::swap - throw iff the
copy constructor of some template type argument throws.
> That's a whole other bag 'o' worms ;-)
And a big one, but I think it will have big benfits ...
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly <llewelly.at@xmission.dot.com>
Date: Fri, 3 Sep 2004 03:43:17 GMT Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") writes:
> "llewelly" <llewelly.at@xmission.dot.com> wrote in message news:868ybxxw1v.fsf@Zorthluthik.local.bar...
> | nesotto@cs.auc.dk ("Thorsten Ottosen") writes:
> |
> | > "llewelly" <llewelly.at@xmission.dot.com> wrote in message news:8665755j0i.fsf@Zorthluthik.local.bar...
>
> | > | So new syntax is required.
> | >
> | > or a change to the standard.
> |
> | I think new syntax would be met with less resistance than changing
> | the meaning of 'throw()', which would change the meaning of
> | existing programs, perhaps detrimentally.
>
> I don't see how it can be "detrimentally"?
>
> There are two cases:
>
> 1. throw() is respected in all ways by the implementation of those functions ==> no change in meaning
> 2. throw() is not respected always ==> program would call terminate(), but now it is allowed to have implementation defined behavior
>
> So I don't see how 2 is any worse than today.
[snip]
It seems you and I had different notions of the change for which 'new
syntax is required'.
I was advocating that C++ introduce staticly checked nothrow;
void foo(int i) nothrow //(**)
{
if(i)
{
throw 1;
}
}
is a compile-time error(*). So I thought you were suggesting that:
void foo(int i) throw()
{
if(i)
{
throw 1;
}
}
become a compile time error.
And so I thought new syntax was required. Now it seems I was wrong to
think you suggesting throw() become staticly checked.
(*) Yes, I know, it's a compile error now :-), but the reason would be
different; it would be a compile time error because a 'nothrow'
function would not be allowed to contain throw expressions, or
calls to functions do not also have nothrow specs.
(**) Provisional syntax. Someone else suggested 'extern "nothrow" ',
which I find equally appealing. It has the advantage of not
requiring a new keyword.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly <llewelly.at@xmission.dot.com>
Date: Fri, 3 Sep 2004 16:20:22 GMT Raw View
nevin@spies.com (Nevin Liber) writes:
> In article <2peg4aFkdpp8U1@uni-berlin.de>,
> Andrei Alexandrescu (See Website for Email) <SeeWebsiteForEmail@moderncppdesign.com> wrote:
>
>>I believe there is an increasing current of opinion (aired several times on
>>this group, and also in this thread and even in your post :o)!) that really
>>exception specifications should be binary (throw or not) and not specify the
>>types being thrown.
>
> I think we need three states, where the third one is "SeeCallee"
> This would be especially helpful for template programming.
>
> Since there is (in theory, anyway :-)) a lot of code that doesn't care
> whether or not the layers below it throw (since it will clean itself up
> correctly either way), it would be nice if it could acquire its exception
> specification from the functions that it calls.
>
> Basically, when I specify "SeeCallee", apply the following rules
> (assuming that the throw isn't isn't guaranteed to be caught inside my
> function, of course):
>
> A. If I directly throw to my caller, my specification is promoted to
> "Throw".
>
> Otherwise,
>
> B. If all of the functions that I call specify "NoThrow", then my
> specification is promoted to "NoThrow".
>
> Otherwise,
>
> C. If at least one of the functions that I call specifies "Throw",
> then my specification is promoted to "Throw".
>
> Otherwise,
>
> D. My specification remains at "SeeCallee".
>
> Of course, having just come up with this, I have no idea how it would
> work with separate compilation, inheritance, virtual functions,
> export, specifications part of function signatures, etc.
>
> Just a thought,
If any of such a function's callees are also 'SeeCallee', the
defintion of the called 'SeeCallee' function must be availible;
void bar() SeeCallee;
void foo() SeeCallee
{
bar();
}
requires the implementation to examine the definition of
SeeCallee. I think the above would have to be made a compile-time
error if the definition of bar was not available. That means
virtual functions and pointers to functions can't be 'SeeCallee'.
I don't think funciton templates, exported or not, are affected,
since the definition of a template must be examined for it to be
instantiated anyway.
I do believe that a way to specify that a function's throw spec is
depenent on the throw specs of the user-provided functions it
calls would be quite useful, and that is like SeeCallee, but
SeeCallee extends the depenency to functions which are not
user-provided. I can't tell if that's better or not.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly <llewelly.at@xmission.dot.com>
Date: Fri, 3 Sep 2004 17:27:05 GMT Raw View
devnull@octopull.demon.co.uk (Alan Griffiths) writes:
> francis@robinton.demon.co.uk (Francis Glassborow) wrote in message news:<1H$ivgHjBwMBFw5Y@robinton.demon.co.uk>...
>>
>> By contrast, a nothrow specification is statically checkable and we can
>> incorporate such into a template library. I think there is good reason
>> to provide a statically enforceable nothrow function modifier into C++
>> along the same lines as const (I.e. it has no runtime relevance).
>
> I agree with much of that, but I think "const" is a poor choice of
> model: I don't think it useful to allow overloading on "nothrow";
> and, we need a convenient mechanism for applying it to imported C APIs
> (i.e. doesn't require editing library headers).
>
> I know I suggested 'extern "nothrow"' with a certain degree of humour,
> but the idea has grown on me.
[snip]
The 'extern "nothrow"' syntax has the advantage of not requiring a
new keyword. :-) I like it because it introduces a word which
says what it means, but dodges the anti-keyword people.
A nothrow block (in addition to nothrow functions) is also a good
idea.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: David Abrahams <dave@boost-consulting.com>
Date: Fri, 3 Sep 2004 22:47:00 GMT Raw View
llewelly <llewelly.at@xmission.dot.com> writes:
> devnull@octopull.demon.co.uk (Alan Griffiths) writes:
>
>> francis@robinton.demon.co.uk (Francis Glassborow) wrote in message news:<1H$ivgHjBwMBFw5Y@robinton.demon.co.uk>...
>>>
>>> By contrast, a nothrow specification is statically checkable and we can
>>> incorporate such into a template library. I think there is good reason
>>> to provide a statically enforceable nothrow function modifier into C++
>>> along the same lines as const (I.e. it has no runtime relevance).
>>
>> I agree with much of that, but I think "const" is a poor choice of
>> model: I don't think it useful to allow overloading on "nothrow";
>> and, we need a convenient mechanism for applying it to imported C APIs
>> (i.e. doesn't require editing library headers).
>>
>> I know I suggested 'extern "nothrow"' with a certain degree of humour,
>> but the idea has grown on me.
> [snip]
>
> The 'extern "nothrow"' syntax has the advantage of not requiring a
> new keyword. :-) I like it because it introduces a word which
> says what it means, but dodges the anti-keyword people.
Given that we already have
throw()
I like Howard's suggestion
static throw()
a lot better.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Ben Strasser <ben04_01@freenet.de>
Date: Sat, 4 Sep 2004 23:21:56 GMT Raw View
David Abrahams wrote:
>
>>The 'extern "nothrow"' syntax has the advantage of not requiring a
>> new keyword. :-) I like it because it introduces a word which
>> says what it means, but dodges the anti-keyword people.
>
>
> Given that we already have
>
> throw()
>
> I like Howard's suggestion
>
> static throw()
>
> a lot better.
>
I'm for
extern throw(){
//...
}
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: devnull@octopull.demon.co.uk (Alan Griffiths)
Date: Mon, 6 Sep 2004 15:24:13 GMT Raw View
David Abrahams <dave@boost-consulting.com> wrote in message news:<uy8jrm35t.fsf@boost-consulting.com>...
> llewelly <llewelly.at@xmission.dot.com> writes:
>
> > The 'extern "nothrow"' syntax has the advantage of not requiring a
> > new keyword. :-) I like it because it introduces a word which
> > says what it means, but dodges the anti-keyword people.
>
>
> Given that we already have
>
> throw()
>
> I like Howard's suggestion
>
> static throw()
>
> a lot better.
That is a nice syntax. But doesn't leave an easy way to interface to
third party code (especially C APIs) that neither throws nor has this
in the function signature.
I think that being able to say:
#ifdef __cplusplus
extern "nothrow" {
#endif
/* ...some C code... */
#ifdef __cplusplus
}
#endif
allows an easier migration path. Especially when "some C code" is a
header from a library I don't control.
--
Alan Griffiths
http://www.octopull.demon.co.uk/
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Mon, 30 Aug 2004 17:58:52 GMT Raw View
"Alf P. Steinbach" <alfps@start.no> wrote in message
news:41321141.78572593@news.individual.net...
> Unfortunately, even after being told thrice MSVC 7.1 insists on a warning
> about unreachable code.
I can't reproduce the warning, even on warning level 4 (in msvc). Could you
post a complete example so I can paste it in? I don't get a warning to save
my life.
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 30 Aug 2004 21:07:19 GMT Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:
> "David Abrahams" <dave@boost-consulting.com> wrote in message
> news:uzn4dtma4.fsf@boost-consulting.com...
>> SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website
>> for Email)") writes:
>>
>>> A swap that doesn't throw versus one that throws is the difference
>>> between a correct and an incorrect function.
>>
>> Careful. Some people have set up the expectation that swap shouldn't
>> throw, but it's by no means a requirement.
>
> Not sure I understand. For example, the copy via swap algorithm
"copy via swap algorithm?" Never heard of it.
> is useful iff swap doesn't throw. I guess there are other examples
> when indeed code could work whether or not swap could throw, but
> most of the code I write hopes for a nonthrowing (and cheap)
> swap.
Exactly. There's no standard requirement that your swaps be
nonthrowing, and there's no a priori reason why swap shouldn't throw.
> Would be great if swap's nonthrowingness would be verified
> statically...
That's a whole other bag 'o' worms ;-)
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: mlanzkron@yahoo.co.uk (Motti Lanzkron)
Date: Tue, 31 Aug 2004 04:21:09 GMT Raw View
Motti Lanzkron wrote:
>It was a nice intellectual challenge but since it doesn't seem to work
>when T is a non const references I think that's all it can be.
If I change the cast operator so that it casts to T& instead of T all
bases seem to be covered (except for void for which I started a new
thread in comp.lang.c++.moderated).
class no_return {
no_return(); // prevent creation
template<class T> T* dummy() { return 0; }
public:
template<class T>
operator T&()
{
return *dummy<T>();
}
};
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Tue, 31 Aug 2004 04:33:20 GMT Raw View
* "Andrei Alexandrescu (See Website for Email)":
> "Alf P. Steinbach" <alfps@start.no> wrote in message
> news:41321141.78572593@news.individual.net...
> > Unfortunately, even after being told thrice MSVC 7.1 insists on a warning
> > about unreachable code.
>
> I can't reproduce the warning, even on warning level 4 (in msvc). Could you
> post a complete example so I can paste it in? I don't get a warning to save
> my life.
Just Motti's original example modified to use "return throw":
#include <cassert>
class none {
none(); // prevent creation
public:
template<class T>
operator T ()
{
assert( false );
return throw throw throw "";
//assert( "none::operator T(): should never be executed" );
//return *(T*)(0);
}
};
none Exit(int code)
{
throw code; // If "return throw code" then compile error.
}
int f(bool b)
{
if (b)
return 42;
Exit(1); // Line 25.
}
double f(double* p)
{
if(p == 0)
Exit(2); // Line 31.
return *p;
}
int main( int argc, char * args[] )
{
f( argc == 5 );
double d = (argc == 5? 1: 0);
f(&d);
}
Compiling (Windows standard command interpreter):
Q:\> cl /c /GX /GR /W4 /O2 main.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x8
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
main.cpp
main.cpp(35) : warning C4100: 'args' : unreferenced formal parameter
q:\main.cpp(25) : warning C4702: unreachable code
q:\main.cpp(31) : warning C4702: unreachable code
Q:\> _
The unreachable code warnings disappear if I turn off optimization (option
O2) but then, I have that option on by default in my "test" project that I
use for such things.
So, it seems this technique is at least currently not Boost'able, but
perhaps Boost'ing it would encourage Microsoft and perhaps also other
vendors to fix things, and standardizing it -- or as I've argued, function
attribute notation -- would perhaps more certainly have that effect.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: pasa@lib.hu ("Balog Pal")
Date: Tue, 31 Aug 2004 15:32:27 GMT Raw View
"Alf P. Steinbach" <alfps@start.no> wrote in message
news:413372b1.169051906@news.individual.net...
> The unreachable code warnings disappear if I turn off optimization (option
> O2) but then, I have that option on by default in my "test" project that I
> use for such things.
MSVC has a long history to produce 'unreachable code' warnings with
optimisation, for no sane reason. Sometimes the code is rearranged in a
wierd way, then put to the analyser that emits the warning. I recall it
once emitted a JMP behind another JMP, then warned about it.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: devnull@octopull.demon.co.uk (Alan Griffiths)
Date: Tue, 31 Aug 2004 17:16:55 GMT Raw View
francis@robinton.demon.co.uk (Francis Glassborow) wrote in message news:<1H$ivgHjBwMBFw5Y@robinton.demon.co.uk>...
>
> By contrast, a nothrow specification is statically checkable and we can
> incorporate such into a template library. I think there is good reason
> to provide a statically enforceable nothrow function modifier into C++
> along the same lines as const (I.e. it has no runtime relevance).
I agree with much of that, but I think "const" is a poor choice of
model: I don't think it useful to allow overloading on "nothrow";
and, we need a convenient mechanism for applying it to imported C APIs
(i.e. doesn't require editing library headers).
I know I suggested 'extern "nothrow"' with a certain degree of humour,
but the idea has grown on me.
--
Alan Griffiths
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: nevin@spies.com (Nevin Liber)
Date: Tue, 31 Aug 2004 19:23:49 GMT Raw View
In article <2peg4aFkdpp8U1@uni-berlin.de>,
Andrei Alexandrescu (See Website for Email) <SeeWebsiteForEmail@moderncppdesign.com> wrote:
>I believe there is an increasing current of opinion (aired several times on
>this group, and also in this thread and even in your post :o)!) that really
>exception specifications should be binary (throw or not) and not specify the
>types being thrown.
I think we need three states, where the third one is "SeeCallee"
This would be especially helpful for template programming.
Since there is (in theory, anyway :-)) a lot of code that doesn't care
whether or not the layers below it throw (since it will clean itself up
correctly either way), it would be nice if it could acquire its exception
specification from the functions that it calls.
Basically, when I specify "SeeCallee", apply the following rules
(assuming that the throw isn't isn't guaranteed to be caught inside my
function, of course):
A. If I directly throw to my caller, my specification is promoted to
"Throw".
Otherwise,
B. If all of the functions that I call specify "NoThrow", then my
specification is promoted to "NoThrow".
Otherwise,
C. If at least one of the functions that I call specifies "Throw",
then my specification is promoted to "Throw".
Otherwise,
D. My specification remains at "SeeCallee".
Of course, having just come up with this, I have no idea how it would
work with separate compilation, inheritance, virtual functions,
export, specifications part of function signatures, etc.
Just a thought,
--
Nevin ":-)" Liber <mailto:nevin@spies.com> (773) 961-1620
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Tue, 31 Aug 2004 21:21:47 GMT Raw View
"Motti Lanzkron" <mlanzkron@yahoo.co.uk> wrote in message
news:mbf5j0hnspituo7724mcjfcacqkop9ekb5@4ax.com...
> If I change the cast operator so that it casts to T& instead of T all
> bases seem to be covered (except for void for which I started a new
> thread in comp.lang.c++.moderated).
>
> class no_return {
> no_return(); // prevent creation
> template<class T> T* dummy() { return 0; }
> public:
> template<class T>
> operator T&()
> {
> return *dummy<T>();
> }
> };
This class (combined perhaps with throwing instead of returning dummy) is
really cool. It's a nice example of active documentation, where the
programmer makes it clear that the function will never return normally, and
also gives an excellent clue to the compiler, which can generate better code
(and warnings, albeit MSVC's overly keen optimizer's warning is a
counterexample).
If we could also find some examples of standard functions that could return
"std::none", that would make it a good candidate for standardization. But
the standard has no infinite message loops and changing the return type of
std::exit() and std::abort() is not practical... sigh.
FWIW, this is not my idea; it's used in the Cecil language, which has "none"
that is a subclass of everything, and "all" that is a discriminated union of
everything. (That's what makes me fond of the name "none" as well.)
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: usenet-nospam@nmhq.net (Niklas Matthies)
Date: Sat, 28 Aug 2004 21:31:16 GMT Raw View
On 2004-08-28 04:01, "Marcin 'Qrczak' Kowalczyk" wrote:
:
> 2. exception specifications should be used always or never - if the
> language doesn't require exception specifications in all cases, then
> places which want to specify exceptions, but use some functions which
> didn't specify their exceptions, are in trouble;
Why?
Functions which don't specify their exceptions are equivalent to
functions that specify that they can throw anything.
And for the calling function this is just a special case of the more
general case that it calls functions that specify exceptions that the
calling function doesn't specify.
-- Niklas Matthies
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Sat, 28 Aug 2004 21:31:46 GMT Raw View
* "Andrei Alexandrescu (See Website for Email)":
>
> I've been thinking of how operator T() should look like... would a better
> approach be to have operator T() throw something? That way, the compiler
> won't ask for any return statement and won't be confused by the recursion:
>
> class none {
> none(); // prevent creation
> public:
> template<class T>
> operator T()
> {
> assert(!"Execution should never reach this point.");
> throw "Boo!";
> }
> };
MSVC 7.1 still reports "unreachable code".
MSVC 7.1 issues a warning for any 'throw' whether it's in 'none::operator
T()' or in the function called via that mechanism, unless this compiler's
non-standard extension for specifying "no return ever" is used and the
return type of the non-returning function is 'void'.
This last means that even though 'none' could work as a standardized feature
it seems that it cannot work as e.g. a Boost class... :-(
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: devnull@octopull.demon.co.uk (Alan Griffiths)
Date: Sat, 28 Aug 2004 21:32:03 GMT Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") wrote in message news:<2p9glrFics8sU1@uni-berlin.de>...
>
> Exactly. I don't know why C++ people hate static exception specs that much.
> Agreed, Java didn't really get to Nirvana, but maybe it's at a higher
> altitude.
Static exception specs in the Java model are not appropriate for the
long range nature of C++ exceptions. Nor are they easy to deal with
when writing template code.
> A swap that doesn't throw versus one that throws is the difference between a
> correct and an incorrect function. It would be nice to have that statically
> checked, as your code shows.
But here we are talking a different model: marking out blocks of code
and functions that *do not throw* exceptions (and statically checking
that). This is distinct from checking the range of exceptions that
are being propagated.
Staying with this model - as opposed to the Java one - it would also
be useful to mark and statically check the "basic" guarantee.
(Automating checking of the "strong" guarantee would be problematic.)
--
Alan Griffiths
http://www.octopull.demon.co.uk/
-
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk")
Date: Sat, 28 Aug 2004 23:53:42 GMT Raw View
usenet-nospam@nmhq.net (Niklas Matthies) writes:
>> 2. exception specifications should be used always or never - if the
>> language doesn't require exception specifications in all cases, then
>> places which want to specify exceptions, but use some functions which
>> didn't specify their exceptions, are in trouble;
>
> Why?
> Functions which don't specify their exceptions are equivalent to
> functions that specify that they can throw anything.
Then there are plenty of cases where the function will throw no
exceptions outside some set but the compiler doesn't know this.
What do you do if you want to call a function without an exception
specification from a function with a specification? Assume that you
double checked the documentation / source that it should not throw
anything not included in the specification of the caller.
1. Weaken the specification of the caller? Then its callers will have
to be similarly modified, and up all possible call chains. A little
but important inner function from some library not using exception
specifications might destroy half of exception specifications of
the project. And changing a signature is not always possible.
2. Include some construct which says "hey compiler, trust me, there
will be no other exceptions"? Then if you made a mistake and the
function did in fact throw something else, you get undefined
behavior instead of running some handler.
3. Add 'try {' and '} catch (...) {}'? Then if you made a mistake,
the error is silently ignored and nonsensical results are treated
as valid.
4. Let the compiler insert runtime checks? This is what we have now.
We know the consequence: exception specifications are little used.
It's not necessarily wrong. Maybe statically specifying exceptions
is not much easier than ensuring that division by zero does not
occur, and it's better to handle it at runtime.
--
__("< Marcin Kowalczyk
\__/ qrczak@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: usenet-nospam@nmhq.net (Niklas Matthies)
Date: Sun, 29 Aug 2004 04:47:26 GMT Raw View
On 2004-08-28 23:53, "Marcin 'Qrczak' Kowalczyk" wrote:
> usenet-nospam@nmhq.net (Niklas Matthies) writes:
>
>>> 2. exception specifications should be used always or never - if the
>>> language doesn't require exception specifications in all cases, then
>>> places which want to specify exceptions, but use some functions which
>>> didn't specify their exceptions, are in trouble;
>>
>> Why?
>> Functions which don't specify their exceptions are equivalent to
>> functions that specify that they can throw anything.
>
> Then there are plenty of cases where the function will throw no
> exceptions outside some set but the compiler doesn't know this.
> What do you do if you want to call a function without an exception
> specification from a function with a specification? Assume that you
> double checked the documentation / source that it should not throw
> anything not included in the specification of the caller.
Catch and rethrow those exceptions that the function should propagate,
and assert() (or equivalent) on any other exceptions.
It implies a little bit of boilerplate code (I do this routinely in
Java and don't find it particularly bothersome--I even like it because
it documents intent), but I certainly cannot see how this means that
the calling function is "in trouble".
And with adequate metaprogramming support the syntax could be made
more lightweight.
> 2. Include some construct which says "hey compiler, trust me, there
> will be no other exceptions"?
That could be an alternative for avoiding the runtime checks.
In fact, simply replacing the assert() with compile-time-detectable
UB would enable the compiler to optimize away all the catch clauses
involved. (Which gets us back to the old assume() proposal.)
> Then if you made a mistake and the function did in fact throw
> something else, you get undefined behavior instead of running
> some handler.
Right. Either you want safety, which comes at a runtime cost, or
you want maximum efficiency even for the exceptional case, then you
have to trust yourself to get things right. That sort of trade-off
is not particularly uncommon in C++. It happens every time you
dereference a pointer without checking for null, for example.
> 4. Let the compiler insert runtime checks? This is what we have now.
Yes, what we have now happens to be a reasonable behavior for the
particular situation you described above, but it is, in general, not
the desired behavior when the called functions have an exception
specification that is not a subset of the caller's specification.
-- Niklas Matthies
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: mlanzkron@yahoo.co.uk (Motti Lanzkron)
Date: Sun, 29 Aug 2004 08:11:11 GMT Raw View
Alf P. Steinbach wrote:
>* Motti Lanzkron:
>> * Andrei Alexandrescu:
>> > * Motti Lanzkron"
>> > > * Alf P. Steinbach wrote:
>> > > >
>> > > > On the third hand,
>> > >
>> > > ITYM on the gripping hand ;o)
>
>There was a mote flying around that distracted me.
>
>
>> > > > I think there _is_ a need to be able to specify that a
>> > > > function won't ever return, e.g. functions like "throwX()" or "exit()", so
>> > > > as to avoid silly compiler warnings about "not all paths returning a
>> > > > value"
>> >
>> > An elegant way is to have the function return a built-in type "none", which
>> > is by definition a subtype of all types in the program:
>>
>> Let's see...
>>
>> class none {
>> none(); // prevent creation
>> public:
>> // Is this allowed?
>> template<class T>
>> operator T()
>> {
>> // This will never run as no instance of this class
>> // can be created. Fool the linker by recursing.
>> return *this;
>> }
>> };
>>
>> none Exit(int code) { throw code; } // placeholder..
>
>You reported that it didn't compile well with MSVC 6.0 (if I interpreted
>the version number correctly).
Actually it's "Microsoft Visual C++ Toolkit 2003" I downloaded the
free command line compiler, but I got the same thing with VS6.
>It does compile with MSVC 7.1, but with the following warnings:
>
>main.cpp(11) : warning C4717: 'none::operator<int> int' : recursive on all
>control paths, function will cause runtime stack overflow
>main.cpp(11) : warning C4717: 'none::operator<double> double' : recursive on
>all control paths, function will cause runtime stack overflow
Pity, I thought the recursive part was cute.
>main.cpp(20) : warning C4702: unreachable code
>main.cpp(26) : warning C4702: unreachable code
Well if I count lines correctly these warnings are irrelevant, it's
just because the compiler sees what arguments the functions are
getting, if the bool was changed from 'true' to something the compiler
couldn't deduce at compile time the warning would go away (ditto for
the pointer not being null).
>
>To fix the that I changed the 'none' definition to
>
> class none {
> none(); // prevent creation
> template<class T> static T* dummy(){ return 0; }
> public:
> // Is this allowed?
> template<class T>
> operator T()
> {
> // This will never run as no instance of this class
> // can be created.
> return *dummy<T>();
Well at first I wrote it as:
return *static_cast<T*>(0);
But even though I know it will never run dereferencing a null pointer
bothered me (just paranoid I guess).
> }
> };
>
>and commented out the statements in 'main', however the warnings about
>unreachable code (due to the 'throw' in Exit) still remained.
Are you sure the warnings were due to the throw? Do they still happen
with this main?
int main(int argc, char** argv)
{
bool b = argc == 7;
f(b);
double d = 0;
f(b? &d : 0);
}
>So, since the aim is to get rid of silly warnings in a portable way, it
>seems that this requires language support after all, as Andrei hinted.
>
>And then, even though this idea is veeeeery cool, I think it would be better
>to add just a single thing to the standard, namely some way to specify
>function attributes. That could serve multiple purposes. E.g. as
>mentioned, DBC, and calling convention, and external linkage name, etc.
It was a nice intellectual challenge but since it doesn't seem to work
when T is a non const references I think that's all it can be.
Oh well, it was fun while it lasted...
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Sun, 29 Aug 2004 16:24:05 GMT Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:
> "Alan Griffiths" <devnull@octopull.demon.co.uk> wrote in message
> news:8ab0685f.0408270242.7cf1f5c3@posting.google.com...
>> dave@boost-consulting.com (David Abrahams) wrote in message
>> news:<uekluyawr.fsf@boost-consulting.com>...
>> I think there is value in statically checking "nothrow", but that it
>> goes beyond function attributes. I'd like to extend it to other
>> blocks, Vis:
>>
>> foo& foo::operator=(const foo& rhs)
>> {
>> foo tmp(rhs);
>>
>> extern "nothrow"
>> {
>> swap(tmp); // Compiler enforces this is a nothrow
>> expression
>> }
>> }
>
> Exactly. I don't know why C++ people hate static exception specs
> that much.
I think there are several issues.
(a) When most people think of static exception specs they think of
all the stupid amounts of effort they spent fixing the throw
specs on forty layers of Java functions.
(b) The ability to list types in an exception spec is the most
obvious and most over-stressed feature of exception specs. Yet
the type of an exception is only important to the handler - the n
layers inbetween only care whether an exception may be thrown,
not what type it is. So as soon as a the type list is staticly
checked, exception handling undergoes a surprising transformation
- it goes from being a tool for non-local error handling to being
a tool for forcing local handling, and yet retained the same
name. I think this causes misuse and over-use of static lists of
exception types in Java (relating back to (a)).
(c) A static nothrow spec, which is actually useful to all layers
between the function which encouters the error and the one that
handles it (in part because it *doesn't* list specific types) is
overshaded by the specific type lists.
(d) In C++1998, the exception specs are so mal-designed it is
difficult to concieve of any use for them.
(e) If Java reccomends it, it must be bad. :-)
> Agreed, Java didn't really get to Nirvana, but maybe it's at a higher
> altitude.
Considering only semantics, I would agree that they did. But custom
in Java (which the language does *not* enforce) is to focus on
listing types in exception specs, even for errors which shouldn't
or can't be handled locally. Once custom is taken into account,
I'm not sure they are better off.
> A swap that doesn't throw versus one that throws is the difference between a
> correct and an incorrect function. It would be nice to have that statically
> checked, as your code shows.
[snip]
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Sun, 29 Aug 2004 16:24:28 GMT Raw View
qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk") writes:
> usenet-nospam@nmhq.net (Niklas Matthies) writes:
>
>>> 2. exception specifications should be used always or never - if the
>>> language doesn't require exception specifications in all cases, then
>>> places which want to specify exceptions, but use some functions which
>>> didn't specify their exceptions, are in trouble;
>>
>> Why?
>> Functions which don't specify their exceptions are equivalent to
>> functions that specify that they can throw anything.
>
> Then there are plenty of cases where the function will throw no
> exceptions outside some set but the compiler doesn't know this.
> What do you do if you want to call a function without an exception
> specification from a function with a specification? Assume that you
> double checked the documentation / source that it should not throw
> anything not included in the specification of the caller.
>
> 1. Weaken the specification of the caller? Then its callers will have
> to be similarly modified, and up all possible call chains. A little
> but important inner function from some library not using exception
> specifications might destroy half of exception specifications of
> the project. And changing a signature is not always possible.
You're focusing on the lists of specific types. Forget them, and
focus on nothrow versus throw. *EVERY* layer between the throw
point and the catch point cares about throw vs nothrow - without
that knowledge, you can't have exception safety. But only the
catchpoint cares about the specific type.
A side benefit is that static exception specs which couldn't list
specific types would much, much easier to describe, and therefor
easier and less risky to add to the language.
>
> 2. Include some construct which says "hey compiler, trust me, there
> will be no other exceptions"? Then if you made a mistake and the
> function did in fact throw something else, you get undefined
> behavior instead of running some handler.
[snip]
No. You get a compile time error.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 29 Aug 2004 16:24:53 GMT Raw View
"Alf P. Steinbach" <alfps@start.no> wrote in message
news:4130eb7d.3368406@news.individual.net...
>* "Andrei Alexandrescu (See Website for Email)":
>>
>> I've been thinking of how operator T() should look like... would a better
>> approach be to have operator T() throw something? That way, the compiler
>> won't ask for any return statement and won't be confused by the
>> recursion:
>>
>> class none {
>> none(); // prevent creation
>> public:
>> template<class T>
>> operator T()
>> {
>> assert(!"Execution should never reach this point.");
>> throw "Boo!";
>> }
>> };
>
> MSVC 7.1 still reports "unreachable code".
Sorry, I meant:
return throw "Boo!";
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Sun, 29 Aug 2004 20:12:35 GMT Raw View
qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk") writes:
> On Fri, 27 Aug 2004 19:42:35 +0000, Andrei Alexandrescu (See Website for
> Email) wrote:
>
>> I don't know why C++ people hate static exception specs that much.
>
> Maybe because
>
> 1. they are impractical for templates, whose exceptional behavior
> depends on that of functions used in them, which is hard to describe
> formally in the type system; especially as
[snip]
First, this isn't only true for templates - *any* function which
which calls functions chosen by the caller of the function
encounters this issue. Second, the problem is greatly reduced if
one specificies only throw or nothrow - it's the type lists that
make it truly awful. And the type lists are the least useful part
of exception specs.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Sun, 29 Aug 2004 21:58:22 GMT Raw View
* Andrei Alexandrescu:
> * Alf P. Steinbach:
> >* Andrei Alexandrescu:
> > >
> > > I've been thinking of how operator T() should look like... would a better
> > > approach be to have operator T() throw something? That way, the compiler
> > > won't ask for any return statement and won't be confused by the
> > > recursion:
> > >
> > > class none {
> > > none(); // prevent creation
> > > public:
> > > template<class T>
> > > operator T()
> > > {
> > > assert(!"Execution should never reach this point.");
> > > throw "Boo!";
> > > }
> > > };
> >
> > MSVC 7.1 still reports "unreachable code".
>
> Sorry, I meant:
>
> return throw "Boo!";
>
Heh, I didn't know you could do that. May I suggest instead
assert(( "Execution should never reach this point", false ));
return throw throw throw "Boo!";
? :-)
All Good Things being three, and this also being allowed by 5.17/1?
Unfortunately, even after being told thrice MSVC 7.1 insists on a warning
about unreachable code.
And interestingly, when the Exit function from the original example is coded
as
none Exit(int code)
{
return throw code;
}
the compiler says
main.cpp(18) : error C2664: 'none::none(const none &)' : cannot convert
parameter 1 from 'void' to 'const none &'
Expressions of type void cannot be converted to other types
main.cpp(18) : error C2553: no legal conversion of return value to return
type 'none'
Is this standard-conforming behavior?
I cannot find anywhere the standard mentions a type for a throw expression.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sun, 29 Aug 2004 22:26:01 GMT Raw View
"llewelly" <llewelly.at@xmission.dot.com> wrote in message
news:863c2617sx.fsf@Zorthluthik.local.bar...
> (a) When most people think of static exception specs they think of
> all the stupid amounts of effort they spent fixing the throw
> specs on forty layers of Java functions.
:o) Sounds like const-specifications.
> (b) The ability to list types in an exception spec is the most
> obvious and most over-stressed feature of exception specs. Yet
> the type of an exception is only important to the handler - the n
> layers inbetween only care whether an exception may be thrown,
> not what type it is. So as soon as a the type list is staticly
> checked, exception handling undergoes a surprising transformation
> - it goes from being a tool for non-local error handling to being
> a tool for forcing local handling, and yet retained the same
> name. I think this causes misuse and over-use of static lists of
> exception types in Java (relating back to (a)).
I believe there is an increasing current of opinion (aired several times on
this group, and also in this thread and even in your post :o)!) that really
exception specifications should be binary (throw or not) and not specify the
types being thrown. In Java it's not really that bad because people can
write:
void foo() throw(Exception) { ... }
which kinda covers everything. It would be nice if standard C++ would add
two specifications, namely:
void foo() throw(...);
meaning "foo might throw just about anything", and:
void foo() throw(std::none);
where "none" is the type mentioned in another subthread of this thread.
Now I realize we already have the first spec, spelled simply:
void foo();
because implcitly a function can throw anything. But the two new specs would
enable static checking by the compiler. So maybe we could have both.
> (c) A static nothrow spec, which is actually useful to all layers
> between the function which encouters the error and the one that
> handles it (in part because it *doesn't* list specific types) is
> overshaded by the specific type lists.
<nod>
> (d) In C++1998, the exception specs are so mal-designed it is
> difficult to concieve of any use for them.
<no muscle moves on my face>
> (e) If Java reccomends it, it must be bad. :-)
<no muscle moves on my face>
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sarima@friesen.net (Stanley Friesen)
Date: Mon, 30 Aug 2004 01:17:35 GMT Raw View
qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk") wrote:
>
>1. Weaken the specification of the caller? Then its callers will have
> to be similarly modified, and up all possible call chains. A little
> but important inner function from some library not using exception
> specifications might destroy half of exception specifications of
> the project. And changing a signature is not always possible.
>
>2. Include some construct which says "hey compiler, trust me, there
> will be no other exceptions"? Then if you made a mistake and the
> function did in fact throw something else, you get undefined
> behavior instead of running some handler.
>
>3. Add 'try {' and '} catch (...) {}'? Then if you made a mistake,
> the error is silently ignored and nonsensical results are treated
> as valid.
>
>4. Let the compiler insert runtime checks? This is what we have now.
>
> We know the consequence: exception specifications are little used.
> It's not necessarily wrong. Maybe statically specifying exceptions
> is not much easier than ensuring that division by zero does not
> occur, and it's better to handle it at runtime.
Personally, I think #2 is in the spirit of C/C++. It is the lowest cost
solution.
Indeed, wouldn't a simple extension of the cast syntax allow this?
If I could wind back the clock, I would say, make throw() the default
throw specification for all functions, and require adding an explicit
throw specification to ALL functions that can throw exceptions. This
allows the compiler to optimize more easily, and allows for better
compile-time checking.
--
The peace of God be with you.
Stanley Friesen
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Mon, 30 Aug 2004 01:32:01 GMT Raw View
nesotto@cs.auc.dk ("Thorsten Ottosen") writes:
> "llewelly" <llewelly.at@xmission.dot.com> wrote in message news:8665755j0i.fsf@Zorthluthik.local.bar...
>
> | What is being suggest is a staticly-checked no-throw spec. 'throw()'
> | is dynamicly-checked - making it much less useful. And in fact,
> | 'throw()' *can't* be staticly-checked - the standard requires:
> |
> | 15.4/10 :
> | # An implementation shall not reject an expression merely because
> | # when executed it throws or might throw an exception that the
> | # containing function does not allow.
> |
> | So new syntax is required.
>
> or a change to the standard.
I think new syntax would be met with less resistance than changing
the meaning of 'throw()', which would change the meaning of
existing programs, perhaps detrimentally.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Mon, 30 Aug 2004 05:36:07 GMT Raw View
SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)") writes:
> A swap that doesn't throw versus one that throws is the difference between a
> correct and an incorrect function.
Careful. Some people have set up the expectation that swap shouldn't
throw, but it's by no means a requirement.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Mon, 30 Aug 2004 17:28:49 GMT Raw View
"llewelly" <llewelly.at@xmission.dot.com> wrote in message news:868ybxxw1v.fsf@Zorthluthik.local.bar...
| nesotto@cs.auc.dk ("Thorsten Ottosen") writes:
|
| > "llewelly" <llewelly.at@xmission.dot.com> wrote in message news:8665755j0i.fsf@Zorthluthik.local.bar...
| > | So new syntax is required.
| >
| > or a change to the standard.
|
| I think new syntax would be met with less resistance than changing
| the meaning of 'throw()', which would change the meaning of
| existing programs, perhaps detrimentally.
I don't see how it can be "detrimentally"?
There are two cases:
1. throw() is respected in all ways by the implementation of those functions ==> no change in meaning
2. throw() is not respected always ==> program would call terminate(), but now it is allowed to have implementation defined behavior
So I don't see how 2 is any worse than today.
br
Thorsten
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Mon, 30 Aug 2004 17:57:33 GMT Raw View
"David Abrahams" <dave@boost-consulting.com> wrote in message
news:uzn4dtma4.fsf@boost-consulting.com...
> SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website
> for Email)") writes:
>
>> A swap that doesn't throw versus one that throws is the difference
>> between a
>> correct and an incorrect function.
>
> Careful. Some people have set up the expectation that swap shouldn't
> throw, but it's by no means a requirement.
Not sure I understand. For example, the copy via swap algorithm is useful
iff swap doesn't throw. I guess there are other examples when indeed code
could work whether or not swap could throw, but most of the code I write
hopes for a nonthrowing (and cheap) swap. Would be great if swap's
nonthrowingness would be verified statically...
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Mon, 30 Aug 2004 17:57:58 GMT Raw View
In article <hnv4j0htaojip8qmj8butnb588f3qjmu6s@4ax.com>, Stanley Friesen
<sarima@friesen.net> writes
>If I could wind back the clock, I would say, make throw() the default
>throw specification for all functions, and require adding an explicit
>throw specification to ALL functions that can throw exceptions. This
>allows the compiler to optimize more easily, and allows for better
>compile-time checking.
That would have required winding back the clock to pre-C++ days.
However, I still think, as I did circa 1993, that unless exception specs
are statically checkable they are of little use. I also think that in a
language such as C++ the requirement for static checking would impose
excessive maintenance work on legacy code. Not only would the work be
excessive, but it would also be very expensive for high integrity code
as such code would have to be revalidated.
Statically checkable exception specifications have more the feel of
'poisoning' than 'correctness' (i.e. they have the kind of problems that
const has in C rather than the benefits it provides in C++).
It would be possible (though I am not aware that anyone has done it) to
write a code analysis tool that would identify potentially unhandled
exceptions. Such a tool would not need exception specifications but it
would need access to all the source code. I can imagine that exception
specifications might be useful to such a tool as it would allow it to
know of promises made by libraries shipped as object code, but only if
every function in the library had an exception specification.
By contrast, a nothrow specification is statically checkable and we can
incorporate such into a template library. I think there is good reason
to provide a statically enforceable nothrow function modifier into C++
along the same lines as const (I.e. it has no runtime relevance).
--
Francis Glassborow ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Thu, 26 Aug 2004 06:28:21 GMT Raw View
* Daryle Walker:
> In article <ud61g9zci.fsf@boost-consulting.com>,
> dave@boost-consulting.com (David Abrahams) wrote:
>
> > alfps@start.no (Alf P. Steinbach) writes:
> [SNIP]
> > > On the other hand I think the problem is academic, for where efficiency
> > > is so critical that a "throw()" specification is a problem one can simply
> > > omit the specification and perhaps place it in a comment.
>
> What's the point of having specifications if they can't be practically
> checked?
Not that I think this is a good idea, but the point of it is efficiency:
it would be information the compiler could use at its discretion with
guaranteed no run-time cost, and the more information a compiler has, the
more it can do.
> Instead of giving up, let's propose a fix that acknowledges
> that blocking all exceptions is an easier, yet more urgent, problem than
> general exception specifications.
That isn't a problem: we already have the "throw()" syntax for that, which
can be used in e.g. an inline wrapper.
> And you forgot that the check isn't just for efficiency. It can make
> sure that a function won't throw when it's remotely called by something
> outside the current C++ runtime. (I doubt the operating system would
> like a callback function that aborts without using the standard return
> mechanism.)
Here you're presumably only talking about a function defined by the
programmer that would be using the language feature.
For such functions we already have the "try" and "catch" keywords.
Or, for less fine-grained control & options, "throw()".
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 26 Aug 2004 06:28:53 GMT Raw View
"Motti Lanzkron" <mlanzkron@yahoo.co.uk> wrote in message
news:mtuoi0tp49tp6eadsk89aj35r3gcjr5tnj@4ax.com...
> Alf P. Steinbach wrote:
>
>>On the third hand,
> ITYM on the gripping hand ;o)
>
>>I think there _is_ a need to be able to specify that a
>>function won't ever return, e.g. functions like "throwX()" or "exit()", so
>>as to avoid silly compiler warnings about "not all paths returning a
>>value"
>
> I don't know if anything like this is in the works but how about:
>
> void exit(int exit_code) return()
> {
> //...
> }
An elegant way is to have the function return a built-in type "none", which
is by definition a subtype of all types in the program:
none exit(int code)
{
//...
}
Given that the function never returns, a call to it can occur in an
expression that's expected to yield any type.
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Thu, 26 Aug 2004 06:43:38 GMT Raw View
alfps@start.no (Alf P. Steinbach) writes:
>> > In general the compiler can't know whether a call through a function
>> > pointer or to a virtual function declared sans "throw()" will throw
>> > or not, and it can't know that a call to an 'extern "C"' function
>> > won't throw.
>>
>> extern "C" is irrelevant, and orthogonal to exception specifications.
>>
>> extern "C" void foo() throw();
>>
>> is perfectly legal.
>
> Yes, I think so, but that's irrelevant: it's not a practical option to
> fix up e.g. the vendor's C header files with exception specifications.
Then you should say that. Your statement about extern "C" concerns
linkage, and is incorrect. An extern "C" function can be implemented
in C++ and may throw.
> The point is that the programmer may know that a C function can't
> ever throw, while the compiler doesn't and cannot know: that
> knowledge is critical in optimizing a no-throw function that uses
> the C function.
Only on dumb implementations of EH. Otherwise the lack of throw()
will just generate a little extra code but not slow anything down.
Also, the programmer can tell the compiler: just supply your own
declaration of the function.
> What do you think of some general notation for function attributes,
> e.g. a Standard alternative that would include among other things
> the functionality (not syntax) of Microsoft's '__declspec' language
> extension?
Something is needed, but I don't see the relevance here.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: mlanzkron@yahoo.co.uk (Motti Lanzkron)
Date: Thu, 26 Aug 2004 19:27:44 GMT Raw View
"Andrei Alexandrescu (See Website for Email)" wrote:
>"Motti Lanzkron" <mlanzkron@yahoo.co.uk> wrote in message
>news:mtuoi0tp49tp6eadsk89aj35r3gcjr5tnj@4ax.com...
>> Alf P. Steinbach wrote:
>>
>>>On the third hand,
>> ITYM on the gripping hand ;o)
>>
>>>I think there _is_ a need to be able to specify that a
>>>function won't ever return, e.g. functions like "throwX()" or "exit()", so
>>>as to avoid silly compiler warnings about "not all paths returning a
>>>value"
>>
>> I don't know if anything like this is in the works but how about:
>>
>> void exit(int exit_code) return()
>> {
>> //...
>> }
>
>An elegant way is to have the function return a built-in type "none", which
>is by definition a subtype of all types in the program:
>
>none exit(int code)
>{
> //...
>}
>
>Given that the function never returns, a call to it can occur in an
>expression that's expected to yield any type.
So whenever you call such a function you have to return it so as to
avoid the warning?
Let's see...
class none {
none(); // prevent creation
public:
// Is this allowed?
template<class T>
operator T()
{
// This will never run as no instance of this class
// can be created. Fool the linker by recursing.
return *this;
}
};
none Exit(int code) { throw code; } // placeholder..
int f(bool b)
{
if (b)
return 42;
return Exit(1);
}
double f(double* p)
{
if(p == 0)
return Exit(2);
return *p;
}
int main()
{
f(true);
double d = 0;
f(&d);
}
Cool, it works with CC and crashes cl with an internal compiler error
[I'm not sure which part is cooler ;o)].
Of course void functions are a problem. In regular functions you can
just not return the "none" value but in templates it's more
problematic.
Compilers used:
CC = CC: Sun WorkShop 6 update 2 C++ 5.3 Patch 111685-06 2002/03/09
cl = Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804
for 80x86
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Thu, 26 Aug 2004 21:48:17 GMT Raw View
* Motti Lanzkron:
> * Andrei Alexandrescu:
> > * Motti Lanzkron"
> > > * Alf P. Steinbach wrote:
> > > >
> > > > On the third hand,
> > >
> > > ITYM on the gripping hand ;o)
There was a mote flying around that distracted me.
> > > > I think there _is_ a need to be able to specify that a
> > > > function won't ever return, e.g. functions like "throwX()" or "exit()", so
> > > > as to avoid silly compiler warnings about "not all paths returning a
> > > > value"
> >
> > An elegant way is to have the function return a built-in type "none", which
> > is by definition a subtype of all types in the program:
>
> Let's see...
>
> class none {
> none(); // prevent creation
> public:
> // Is this allowed?
> template<class T>
> operator T()
> {
> // This will never run as no instance of this class
> // can be created. Fool the linker by recursing.
> return *this;
> }
> };
>
> none Exit(int code) { throw code; } // placeholder..
You reported that it didn't compile well with MSVC 6.0 (if I interpreted
the version number correctly).
It does compile with MSVC 7.1, but with the following warnings:
main.cpp(11) : warning C4717: 'none::operator<int> int' : recursive on all
control paths, function will cause runtime stack overflow
main.cpp(11) : warning C4717: 'none::operator<double> double' : recursive on
all control paths, function will cause runtime stack overflow
main.cpp(20) : warning C4702: unreachable code
main.cpp(26) : warning C4702: unreachable code
To fix the that I changed the 'none' definition to
class none {
none(); // prevent creation
template<class T> static T* dummy(){ return 0; }
public:
// Is this allowed?
template<class T>
operator T()
{
// This will never run as no instance of this class
// can be created.
return *dummy<T>();
}
};
and commented out the statements in 'main', however the warnings about
unreachable code (due to the 'throw' in Exit) still remained.
So, since the aim is to get rid of silly warnings in a portable way, it
seems that this requires language support after all, as Andrei hinted.
And then, even though this idea is veeeeery cool, I think it would be better
to add just a single thing to the standard, namely some way to specify
function attributes. That could serve multiple purposes. E.g. as
mentioned, DBC, and calling convention, and external linkage name, etc.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Thu, 26 Aug 2004 21:58:01 GMT Raw View
"Motti Lanzkron" <mlanzkron@yahoo.co.uk> wrote in message
news:mgnri0lv8l6ra6hpl4lc8u9gejpvm79077@4ax.com...
> So whenever you call such a function you have to return it so as to
> avoid the warning?
>
> Let's see...
>
> class none {
> none(); // prevent creation
> public:
> // Is this allowed?
> template<class T>
> operator T()
> {
> // This will never run as no instance of this class
> // can be created. Fool the linker by recursing.
> return *this;
> }
> };
That looks pretty cool... deserves a place in the standard; could be the
type of a throw-expression or any function that never returns.
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Fri, 27 Aug 2004 02:25:58 GMT Raw View
* David Abrahams:
> * Alf P. Steinbach:
>
> > The point is that the programmer may know that a C function can't
> > ever throw, while the compiler doesn't and cannot know: that
> > knowledge is critical in optimizing a no-throw function that uses
> > the C function.
>
> Only on dumb implementations of EH. Otherwise the lack of throw()
> will just generate a little extra code but not slow anything down.
Okay, so that's then the answer to the OP's concern.
> > What do you think of some general notation for function attributes,
> > e.g. a Standard alternative that would include among other things
> > the functionality (not syntax) of Microsoft's '__declspec' language
> > extension?
>
> Something is needed, but I don't see the relevance here.
Explained earlier in the thread: it can easily capture also this case,
if we'd want it to, and it can easily capture also DBC statements, which
are or can be strongly related to exception specifications by specifying
exception guarantees (none, basic, strong, or whatever the terms are),
and which if allowing strong (nothrow) guarantee without also requiring
throw() specification for the function also captures this case.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: mlanzkron@yahoo.co.uk (Motti Lanzkron)
Date: Wed, 25 Aug 2004 17:23:52 GMT Raw View
Alf P. Steinbach wrote:
>On the third hand,
ITYM on the gripping hand ;o)
>I think there _is_ a need to be able to specify that a
>function won't ever return, e.g. functions like "throwX()" or "exit()", so
>as to avoid silly compiler warnings about "not all paths returning a value"
I don't know if anything like this is in the works but how about:
void exit(int exit_code) return()
{
//...
}
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dwalker07@snet.net (Daryle Walker)
Date: Thu, 26 Aug 2004 00:05:25 GMT Raw View
In article <ud61g9zci.fsf@boost-consulting.com>,
dave@boost-consulting.com (David Abrahams) wrote:
> alfps@start.no (Alf P. Steinbach) writes:
[SNIP]
> > On the other hand I think the problem is academic, for where efficiency
> > is so critical that a "throw()" specification is a problem one can simply
> > omit the specification and perhaps place it in a comment.
What's the point of having specifications if they can't be practically
checked? Instead of giving up, let's propose a fix that acknowledges
that blocking all exceptions is an easier, yet more urgent, problem than
general exception specifications.
And you forgot that the check isn't just for efficiency. It can make
sure that a function won't throw when it's remotely called by something
outside the current C++ runtime. (I doubt the operating system would
like a callback function that aborts without using the standard return
mechanism.)
> throw() needn't slow anything down. It might just as well contribute
> to speedup.
But wasn't there a concern that anti-optimizations are more likely. See
the "Exception-specification rationale" section at
<http://www.boost.org/more/lib_guide.htm>.
--
Daryle Walker
Mac, Internet, and Video Game Junkie
dwalker07 AT snet DOT net
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Thu, 26 Aug 2004 00:05:25 GMT Raw View
* David Abrahams:
> alfps@start.no (Alf P. Steinbach) writes:
>
> > * David Abrahams:
> >> * Daryle Walker:
> >>
> >> > The problem is in cases like
> >> >
> >> > long my_c_func( double y ) throw()
> >> >
> >> > This function only uses C-level constructs, so it fundamentally can't
> >> > throw (ignoring the misfeature some compilers have of channeling
> >> > OS-level exceptions through C++). The user thinks the "throw()"
> >> > specifies just that. But instead, the heavy exception filter gets set
> >> > up anyway, to block all exceptions, even though it's never needed.
> >>
> >> Not if it never uses "throw" and all the functions it calls have
> >> nothrow specifications, too.
> >
> > That is an optimization the compiler can make in some cases.
> >
> > In general the compiler can't know whether a call through a function
> > pointer or to a virtual function declared sans "throw()" will throw
> > or not, and it can't know that a call to an 'extern "C"' function
> > won't throw.
>
> extern "C" is irrelevant, and orthogonal to exception specifications.
>
> extern "C" void foo() throw();
>
> is perfectly legal.
Yes, I think so, but that's irrelevant: it's not a practical option to
fix up e.g. the vendor's C header files with exception specifications.
The point is that the programmer may know that a C function can't ever
throw, while the compiler doesn't and cannot know: that knowledge is
critical in optimizing a no-throw function that uses the C function.
The other point is that:
> > On the other hand I think the problem is academic, for where efficiency
> > is so critical that a "throw()" specification is a problem one can simply
> > omit the specification and perhaps place it in a comment.
>
> throw() needn't slow anything down. It might just as well contribute
> to speedup.
Yes, I think we're in agreement there.
What do you think of some general notation for function attributes, e.g.
a Standard alternative that would include among other things the
functionality (not syntax) of Microsoft's '__declspec' language extension?
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Fri, 27 Aug 2004 04:34:31 GMT Raw View
dwalker07@snet.net (Daryle Walker) writes:
> In article <ud61g9zci.fsf@boost-consulting.com>,
> dave@boost-consulting.com (David Abrahams) wrote:
>
>> alfps@start.no (Alf P. Steinbach) writes:
> [SNIP]
>> > On the other hand I think the problem is academic, for where efficiency
>> > is so critical that a "throw()" specification is a problem one can simply
>> > omit the specification and perhaps place it in a comment.
>
> What's the point of having specifications if they can't be practically
> checked? Instead of giving up, let's propose a fix that acknowledges
> that blocking all exceptions is an easier, yet more urgent, problem than
> general exception specifications.
It's not just easier. It's a good deal more useful. Imagine we have
call stack with n function contexts, like this:
function name
0 problem
1 foo
2 bar
.
.
.
n-2 qux
n-1 quxx
n handler
Suppose an exception is thrown from 'problem' and caught in
'handler'. None of foo, bar, qux, quxx, etc, atempt to handle the
exception. They attempt only to provide some guarantee of
exception safety - basic or strong.
Providing a guarantee of exception safety does not require knowing
the types of exceptions that may be thrown, becuase one performs
the same actions regardless.
But it is necessary to know which operations do not throw at all. So
foo, bar, qux, quxx, etc, each have a need functions which are
provably no-throw.
Only handler needs to know the type of exception thrown.
If you have any use for non-local error handling, you will use
a staticly checked no-throw more than a type list exception
specification.
[snip]
> But wasn't there a concern that anti-optimizations are more likely. See
> the "Exception-specification rationale" section at
> <http://www.boost.org/more/lib_guide.htm>.
[snip]
The current semantics of 'throw()' require (very roughly):
void foo()
try
{
/* ... body of foo ... */
}
catch(...)
{
std::unexpected();
}
For an handler-stack based implementation, such as MSVC++, or g++ on
cygwin or mingw, the begining of the try block requires a push and
a setjmp, while then end requires a pop and another setjmp. On
the other hand, if there is no exception spec, none of that needs
to happen.
For a lookup-table based implementation, such as g++ on freebsd or
linux, a try block does not require the push and pops, or the
setjmps, and so niether does an exception specification.
So penalizations are certainly possible. I don't know whether they
are more likely.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: llewelly.at@xmission.dot.com (llewelly)
Date: Fri, 27 Aug 2004 04:34:41 GMT Raw View
alfps@start.no (Alf P. Steinbach) writes:
> * Daryle Walker:
>> In article <ud61g9zci.fsf@boost-consulting.com>,
>> dave@boost-consulting.com (David Abrahams) wrote:
>>
>> > alfps@start.no (Alf P. Steinbach) writes:
>> [SNIP]
>> > > On the other hand I think the problem is academic, for where
>> > > efficiency is so critical that a "throw()" specification is a
>> > > problem one can simply omit the specification and perhaps place
>> > > it in a comment.
>>
>> What's the point of having specifications if they can't be practically
>> checked?
>
> Not that I think this is a good idea, but the point of it is efficiency:
> it would be information the compiler could use at its discretion with
> guaranteed no run-time cost, and the more information a compiler has, the
> more it can do.
>
>
>> Instead of giving up, let's propose a fix that acknowledges
>> that blocking all exceptions is an easier, yet more urgent, problem than
>> general exception specifications.
>
> That isn't a problem: we already have the "throw()" syntax for that, which
> can be used in e.g. an inline wrapper.
'throw()' is already in use, with a different meaning than what is
suggested here.
>
>
>> And you forgot that the check isn't just for efficiency. It can make
>> sure that a function won't throw when it's remotely called by something
>> outside the current C++ runtime. (I doubt the operating system would
>> like a callback function that aborts without using the standard return
>> mechanism.)
>
> Here you're presumably only talking about a function defined by the
> programmer that would be using the language feature.
>
> For such functions we already have the "try" and "catch" keywords.
>
> Or, for less fine-grained control & options, "throw()".
What is being suggest is a staticly-checked no-throw spec. 'throw()'
is dynamicly-checked - making it much less useful. And in fact,
'throw()' *can't* be staticly-checked - the standard requires:
15.4/10 :
# An implementation shall not reject an expression merely because
# when executed it throws or might throw an exception that the
# containing function does not allow.
So new syntax is required.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: f5xz2bk02@sneakemail.com (Davide Bolcioni)
Date: Fri, 27 Aug 2004 08:09:53 GMT Raw View
Daryle Walker ha scritto:
> I think when a function uses an exception specification
>
> void my_func( int x ) throw ( std::exception )
>
> the compiler sets up a framework around the function proper.
[snip, throw() specification]
This is an important special case of having exception specifications
checked at compile time. In the past, among others, I proposed in this
newsgroup a more general approach (look for "Extended exception
specifications" in Google groups) which would look like this:
T func(args) catch(...)
meaning that func() is guaranteed at compile time to let no exception
escape. The proposal also allowed stuff like
T func(args) catch(signal_unsafe)
to flag functions which are safe to call in a signal handler, and have
the static checking of exceptions reject signal handlers directly or
indirectly invoking functions which are not signal safe.
Davide Bolcioni
--
There is no place like /home.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: devnull@octopull.demon.co.uk (Alan Griffiths)
Date: Fri, 27 Aug 2004 19:19:07 GMT Raw View
dave@boost-consulting.com (David Abrahams) wrote in message news:<uekluyawr.fsf@boost-consulting.com>...
> >
> > Yes, I think so, but that's irrelevant: it's not a practical option to
> > fix up e.g. the vendor's C header files with exception specifications.
I don't think it impractical - there is the precident of fixing them
up with 'extern "C"'. (Yes, that took time, but the idea under
discussion requires compiler changes.) So, for the sake of
illustration, suppose we standardised a meaning for 'extern "nothrow"'
and use it inform the compiler that the intent is for the function(s)
not to throw.
> > The point is that the programmer may know that a C function can't
> > ever throw, while the compiler doesn't and cannot know: that
> > knowledge is critical in optimizing a no-throw function that uses
> > the C function.
..
> Also, the programmer can tell the compiler: just supply your own
> declaration of the function.
Which would be far easier (and portable) by writing:
extern "nothrow" {
#include <unistd.h>
}
Than by other means.
> > What do you think of some general notation for function attributes,
> > e.g. a Standard alternative that would include among other things
> > the functionality (not syntax) of Microsoft's '__declspec' language
> > extension?
>
> Something is needed, but I don't see the relevance here.
I think there is value in statically checking "nothrow", but that it
goes beyond function attributes. I'd like to extend it to other
blocks, Vis:
foo& foo::operator=(const foo& rhs)
{
foo tmp(rhs);
extern "nothrow"
{
swap(tmp); // Compiler enforces this is a nothrow
expression
}
}
But maybe the syntax needs some thought. ;)
--
Alan Griffiths
http://www.octopull.demon.co.uk/
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sarima@friesen.net (Stanley Friesen)
Date: Fri, 27 Aug 2004 19:19:58 GMT Raw View
dave@boost-consulting.com (David Abrahams) wrote:
>dwalker07@snet.net (Daryle Walker) writes:
>
>> I think when a function uses an exception specification
>>
>> void my_func( int x ) throw ( std::exception )
>>
>> the compiler sets up a framework around the function proper. Said
>> framework intercepts all exceptions. Exceptions that match the
>> specification list get through, while all others get converted to a
>> special unexpected-exception type.
>
>No, others go to the unexpected handler.
>
>> The problem is in cases like
>>
>> long my_c_func( double y ) throw()
>>
>> This function only uses C-level constructs, so it fundamentally can't
>> throw (ignoring the misfeature some compilers have of channeling
>> OS-level exceptions through C++). The user thinks the "throw()"
>> specifies just that. But instead, the heavy exception filter gets set
>> up anyway, to block all exceptions, even though it's never needed.
>
>Not if it never uses "throw" and all the functions it calls have
>nothrow specifications, too.
I have seen compilers for which this is not the case. The only way to
optimize out exception handling in a function with the compiler we are
using at work is to use a compiler option, which shuts it down for the
entire file. Note, this isn't some obscure compiler, it is a late
version 2 of the Gnu compiler. Now maybe this is fixed in Gnu version
3, but we cannot use that for compatibility reasons.
I found this out when I discovered that merely allowing exceptions in an
interrupt handler tended to cause system crashes, and adding throw() to
all relevant functions did NOT cure the crash. It seems that an
exception enabled function, even one declared throw() that only calls
other such functions, still sets up the exception handling mechanism,
which is what causes the crash in interrupt context.
The only solution we found was to separate all functions called in
interrupt context into separate files and compile those files with the
no-exceptions option. This is an ugly solution, when consistent use of
throw() *should* have fixed it.
--
The peace of God be with you.
Stanley Friesen
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Fri, 27 Aug 2004 19:42:35 GMT Raw View
"Alan Griffiths" <devnull@octopull.demon.co.uk> wrote in message
news:8ab0685f.0408270242.7cf1f5c3@posting.google.com...
> dave@boost-consulting.com (David Abrahams) wrote in message
> news:<uekluyawr.fsf@boost-consulting.com>...
> I think there is value in statically checking "nothrow", but that it
> goes beyond function attributes. I'd like to extend it to other
> blocks, Vis:
>
> foo& foo::operator=(const foo& rhs)
> {
> foo tmp(rhs);
>
> extern "nothrow"
> {
> swap(tmp); // Compiler enforces this is a nothrow
> expression
> }
> }
Exactly. I don't know why C++ people hate static exception specs that much.
Agreed, Java didn't really get to Nirvana, but maybe it's at a higher
altitude.
A swap that doesn't throw versus one that throws is the difference between a
correct and an incorrect function. It would be nice to have that statically
checked, as your code shows.
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: nesotto@cs.auc.dk ("Thorsten Ottosen")
Date: Sat, 28 Aug 2004 02:52:45 GMT Raw View
"llewelly" <llewelly.at@xmission.dot.com> wrote in message news:8665755j0i.fsf@Zorthluthik.local.bar...
| What is being suggest is a staticly-checked no-throw spec. 'throw()'
| is dynamicly-checked - making it much less useful. And in fact,
| 'throw()' *can't* be staticly-checked - the standard requires:
|
| 15.4/10 :
| # An implementation shall not reject an expression merely because
| # when executed it throws or might throw an exception that the
| # containing function does not allow.
|
| So new syntax is required.
or a change to the standard.
br
Thorsten
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: sarima@friesen.net (Stanley Friesen)
Date: Sat, 28 Aug 2004 02:53:01 GMT Raw View
alfps@start.no (Alf P. Steinbach) wrote:
>
>On the other hand I think the problem is academic, for where efficiency
>is so critical that a "throw()" specification is a problem one can simply
>omit the specification and perhaps place it in a comment.
Doesn't always work. The mere act of the function prefix setting up
exception handling context was causing our system to crash (Gnu 2.X).
This was because the exception setup uses new() to allocate some sort of
buffer, which is a no-no in interrupt contexts.
--
The peace of God be with you.
Stanley Friesen
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: qrczak@knm.org.pl ("Marcin 'Qrczak' Kowalczyk")
Date: Sat, 28 Aug 2004 04:01:16 GMT Raw View
On Fri, 27 Aug 2004 19:42:35 +0000, Andrei Alexandrescu (See Website for
Email) wrote:
> I don't know why C++ people hate static exception specs that much.
Maybe because
1. they are impractical for templates, whose exceptional behavior
depends on that of functions used in them, which is hard to describe
formally in the type system; especially as
2. exception specifications should be used always or never - if the
language doesn't require exception specifications in all cases, then
places which want to specify exceptions, but use some functions which
didn't specify their exceptions, are in trouble; so it would be quite
a radical change, which requires changing existing code if it's to be
usable together with code with specified exceptions.
--
__("< Marcin Kowalczyk
\__/ qrczak@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 28 Aug 2004 16:10:20 GMT Raw View
""Marcin 'Qrczak' Kowalczyk"" <qrczak@knm.org.pl> wrote in message
news:pan.2004.08.27.20.10.45.564080@knm.org.pl...
> On Fri, 27 Aug 2004 19:42:35 +0000, Andrei Alexandrescu (See Website for
> Email) wrote:
>
>> I don't know why C++ people hate static exception specs that much.
>
> Maybe because
>
> 1. they are impractical for templates, whose exceptional behavior
> depends on that of functions used in them, which is hard to describe
> formally in the type system; especially as
>
> 2. exception specifications should be used always or never - if the
> language doesn't require exception specifications in all cases, then
> places which want to specify exceptions, but use some functions which
> didn't specify their exceptions, are in trouble; so it would be quite
> a radical change, which requires changing existing code if it's to be
> usable together with code with specified exceptions.
Good points. I was somehow assuming/implying that there would be some
additional mechanisms, including perhaps overloading based on throw()
clauses (swap() comes to mind) and a traits mechanism that can tell what
exceptions an operation can throw.
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: SeeWebsiteForEmail@moderncppdesign.com ("Andrei Alexandrescu (See Website for Email)")
Date: Sat, 28 Aug 2004 19:57:11 GMT Raw View
"Motti Lanzkron" <mlanzkron@yahoo.co.uk> wrote in message
news:mgnri0lv8l6ra6hpl4lc8u9gejpvm79077@4ax.com...
> So whenever you call such a function you have to return it so as to
> avoid the warning?
>
> Let's see...
>
> class none {
> none(); // prevent creation
> public:
> // Is this allowed?
> template<class T>
> operator T()
> {
> // This will never run as no instance of this class
> // can be created. Fool the linker by recursing.
> return *this;
> }
> };
[snip]
> Cool, it works with CC and crashes cl with an internal compiler error
> [I'm not sure which part is cooler ;o)].
I've been thinking of how operator T() should look like... would a better
approach be to have operator T() throw something? That way, the compiler
won't ask for any return statement and won't be confused by the recursion:
class none {
none(); // prevent creation
public:
template<class T>
operator T()
{
assert(!"Execution should never reach this point.");
throw "Boo!";
}
};
Andrei
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dwalker07@snet.net (Daryle Walker)
Date: Tue, 24 Aug 2004 02:49:39 GMT Raw View
I think when a function uses an exception specification
void my_func( int x ) throw ( std::exception )
the compiler sets up a framework around the function proper. Said
framework intercepts all exceptions. Exceptions that match the
specification list get through, while all others get converted to a
special unexpected-exception type.
The problem is in cases like
long my_c_func( double y ) throw()
This function only uses C-level constructs, so it fundamentally can't
throw (ignoring the misfeature some compilers have of channeling
OS-level exceptions through C++). The user thinks the "throw()"
specifies just that. But instead, the heavy exception filter gets set
up anyway, to block all exceptions, even though it's never needed.
We need a more exact solution.
How about
long my_c_func2( double y ) throw void
This means that the function internals fundamentally can't throw, so any
exception accommodations the compiler adds to any function should be
optimized away. Unlike regular specifications, it should be easier for
the compiler to enforce this. Such functions can only have:
1. C-level constructs
2. Calls to other "throw void" functions/methods
3. Anything else, if buttressed with a "catch ( ... )"
Uses:
1. std::auto_ptr, and anything else consisting of C-level code
2. The C-part of the standard library
3. OS-level callbacks, exported DLL functions, and cross-language
code, all of which can't know about the C++ runtime that
contains the exception handling routines
--
Daryle Walker
Mac, Internet, and Video Game Junkie
dwalker07 AT snet DOT net
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 24 Aug 2004 06:41:23 GMT Raw View
dwalker07@snet.net (Daryle Walker) writes:
> I think when a function uses an exception specification
>
> void my_func( int x ) throw ( std::exception )
>
> the compiler sets up a framework around the function proper. Said
> framework intercepts all exceptions. Exceptions that match the
> specification list get through, while all others get converted to a
> special unexpected-exception type.
No, others go to the unexpected handler.
> The problem is in cases like
>
> long my_c_func( double y ) throw()
>
> This function only uses C-level constructs, so it fundamentally can't
> throw (ignoring the misfeature some compilers have of channeling
> OS-level exceptions through C++). The user thinks the "throw()"
> specifies just that. But instead, the heavy exception filter gets set
> up anyway, to block all exceptions, even though it's never needed.
Not if it never uses "throw" and all the functions it calls have
nothrow specifications, too.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: alfps@start.no (Alf P. Steinbach)
Date: Tue, 24 Aug 2004 17:29:39 GMT Raw View
* David Abrahams:
> * Daryle Walker:
>
> > The problem is in cases like
> >
> > long my_c_func( double y ) throw()
> >
> > This function only uses C-level constructs, so it fundamentally can't
> > throw (ignoring the misfeature some compilers have of channeling
> > OS-level exceptions through C++). The user thinks the "throw()"
> > specifies just that. But instead, the heavy exception filter gets set
> > up anyway, to block all exceptions, even though it's never needed.
>
> Not if it never uses "throw" and all the functions it calls have
> nothrow specifications, too.
That is an optimization the compiler can make in some cases.
In general the compiler can't know whether a call through a function
pointer or to a virtual function declared sans "throw()" will throw or not,
and it can't know that a call to an 'extern "C"' function won't throw.
However, the programmer may know this.
On the other hand I think the problem is academic, for where efficiency
is so critical that a "throw()" specification is a problem one can simply
omit the specification and perhaps place it in a comment.
On the third hand, I think there _is_ a need to be able to specify that a
function won't ever return, e.g. functions like "throwX()" or "exit()", so
as to avoid silly compiler warnings about "not all paths returning a value"
and consequent placement of dummy return statements in the code. This
problem goes hand in hand with the problem of specifying calling & linkage
name convention. In both cases the vendors are now forced to define their
own non-standard extensions, some way of specifying function attributes.
And if a unified notation for specifying attributes existed, then perhaps it
could also cover the case of specifying "won't ever throw, no check please".
And be made general enough to later incorporate DBC statements... ;-)
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: terekhov@web.de (Alexander Terekhov)
Date: Tue, 24 Aug 2004 17:30:05 GMT Raw View
David Abrahams wrote:
[...]
> No, others go to the unexpected handler.
The wrong one (and terminate handler that is also foolishly carried
by exceptions in the current C++-lacking-2-phase-EH may also be "out
of scope" and can do quite a damage, not help).
regards,
alexander.
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: dave@boost-consulting.com (David Abrahams)
Date: Tue, 24 Aug 2004 23:48:36 GMT Raw View
alfps@start.no (Alf P. Steinbach) writes:
> * David Abrahams:
>> * Daryle Walker:
>>
>> > The problem is in cases like
>> >
>> > long my_c_func( double y ) throw()
>> >
>> > This function only uses C-level constructs, so it fundamentally can't
>> > throw (ignoring the misfeature some compilers have of channeling
>> > OS-level exceptions through C++). The user thinks the "throw()"
>> > specifies just that. But instead, the heavy exception filter gets set
>> > up anyway, to block all exceptions, even though it's never needed.
>>
>> Not if it never uses "throw" and all the functions it calls have
>> nothrow specifications, too.
>
> That is an optimization the compiler can make in some cases.
>
> In general the compiler can't know whether a call through a function
> pointer or to a virtual function declared sans "throw()" will throw
> or not, and it can't know that a call to an 'extern "C"' function
> won't throw.
extern "C" is irrelevant, and orthogonal to exception specifications.
extern "C" void foo() throw();
is perfectly legal.
BTW, it can also have the same knowledge about inline functions and
function templates using the inclusion model. And of course, the
linker can make further deductions about what can throw in a
whole-program optimization pass, without any exception specifications.
> However, the programmer may know this.
>
> On the other hand I think the problem is academic, for where efficiency
> is so critical that a "throw()" specification is a problem one can simply
> omit the specification and perhaps place it in a comment.
throw() needn't slow anything down. It might just as well contribute
to speedup.
--
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: hinnant@metrowerks.com (Howard Hinnant)
Date: Tue, 24 Aug 2004 23:48:47 GMT Raw View
In article
<dwalker07-805F3A.12493323082004@newsclstr01.news.prodigy.com>,
dwalker07@snet.net (Daryle Walker) wrote:
> We need a more exact solution.
>
> How about
>
> long my_c_func2( double y ) throw void
I agree, but I like this spelling:
long my_c_func2( double y ) static throw();
-Howard
Standardize, but with a sense of humor! :-)
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]