Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Bjarne's comments about exception specification

1 view
Skip to first unread message

George2

unread,
Jan 20, 2008, 4:59:30 AM1/20/08
to
Hello everyone,


How do you understand the Bjarne's comments about exception
specification? Especially, "not required to be checked across
compilation-unit" and "violations will not be caught at run time"?

section 14.6.1 Checking Exception Specifications

--------------------
Importantly, exception-specifications are not required to be checked
exactly across compilation-unit boundaries. Naturally, an
implementation could check. However, for many large and long-lived
systems, it is important that the implementation does not -- or, if it
does, than it carefully gives hard errors only where violations will
not be caught at run time.
--------------------


thanks in advance,
George

Alf P. Steinbach

unread,
Jan 20, 2008, 5:26:38 AM1/20/08
to
* George2:

I wonder where you found that and how old it is.

If it refers to C++ then it's incorrect per the current standard (1998),
and was also incorrect with respect to the 1991 ARM.

§15.4/8 specifies the checking behavior without reference to compilation
units (in the standard referred to as translation units).


Cheers, & hth.,

- Alf

--
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?

Erik Wikström

unread,
Jan 20, 2008, 6:39:46 AM1/20/08
to
On 2008-01-20 11:26, Alf P. Steinbach wrote:
> * George2:
>> Hello everyone,
>>
>>
>> How do you understand the Bjarne's comments about exception
>> specification? Especially, "not required to be checked across
>> compilation-unit" and "violations will not be caught at run time"?
>>
>> section 14.6.1 Checking Exception Specifications
>>
>> --------------------
>> Importantly, exception-specifications are not required to be checked
>> exactly across compilation-unit boundaries. Naturally, an
>> implementation could check. However, for many large and long-lived
>> systems, it is important that the implementation does not -- or, if it
>> does, than it carefully gives hard errors only where violations will
>> not be caught at run time.
>> --------------------
>
> I wonder where you found that and how old it is.
>
> If it refers to C++ then it's incorrect per the current standard (1998),
> and was also incorrect with respect to the 1991 ARM.

It is in the 3rd ed. of TC++PL, but it is taken out of context. I think
he is referring to whether the compiler will give any warnings/errors at
compile-time (though I can not find any mentioning of this in the standard).

Section 14.6.1 starts by talking about checking of exception-
specifications at compile-time and the paragraph after the quoted one
says that the point is that you should not have to go through all your
code and update your exception-specifications just because you make some
change that allows more exceptions to be thrown.

--
Erik Wikström

Alf P. Steinbach

unread,
Jan 20, 2008, 7:11:26 AM1/20/08
to
* Erik Wikström:

> On 2008-01-20 11:26, Alf P. Steinbach wrote:
>> * George2:
>>> Hello everyone,
>>>
>>>
>>> How do you understand the Bjarne's comments about exception
>>> specification? Especially, "not required to be checked across
>>> compilation-unit" and "violations will not be caught at run time"?
>>>
>>> section 14.6.1 Checking Exception Specifications
>>>
>>> --------------------
>>> Importantly, exception-specifications are not required to be checked
>>> exactly across compilation-unit boundaries. Naturally, an
>>> implementation could check. However, for many large and long-lived
>>> systems, it is important that the implementation does not -- or, if it
>>> does, than it carefully gives hard errors only where violations will
>>> not be caught at run time.
>>> --------------------
>> I wonder where you found that and how old it is.
>>
>> If it refers to C++ then it's incorrect per the current standard (1998),
>> and was also incorrect with respect to the 1991 ARM.
>
> It is in the 3rd ed. of TC++PL, but it is taken out of context. I think
> he is referring to whether the compiler will give any warnings/errors at
> compile-time (though I can not find any mentioning of this in the standard).

The standard is quite clear about compile checking.

For certain constructs (overriding a virtual function, assigning or
initializing a function pointer) exception specifications are
effectively required to be checked at compile time.

But in the general case of checking whether a function implementation
violates the function's exception specification, the 98 standard sayeth:

§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"

Following up with an example of a well-formed function (must compile)
that has a stronger exception specification than a function it calls.

In other words, the standard effectively specifies that the code must
compile regardless of what a function's implementation might or
logically must throw; however, a compiler is free to emit diagnostics
(which would in practice be warnings) just as with other constructs.

So I can't make heads or tails of the "checked /exactly/" (emphasis
added) in the quoted passage, with the interpretation of compile time
checking, because with that interpretation they're in general not
required to be checked at all, much less "exactly". Perhaps the OP
could do the honors of checking the TCPPPL errata pages and see whether
this has been reworded.


> Section 14.6.1 starts by talking about checking of exception-
> specifications at compile-time and the paragraph after the quoted one
> says that the point is that you should not have to go through all your
> code and update your exception-specifications just because you make some
> change that allows more exceptions to be thrown.

Yep, and that's what the standard's §15.4/10 is all about.

Cheers,

Ioannis Vranos

unread,
Jan 20, 2008, 7:26:59 AM1/20/08
to
Does anyone use exception specifications in real world? I think they are
difficult to keep complying with them after some time, and are difficult
to be always accurate when defining them.

Erik Wikström

unread,
Jan 20, 2008, 8:06:24 AM1/20/08
to

The empty specification (throw()) is quite useful to indicate that a
function does not throw (can be good to know when dealing with exception
safety). But other than that I do not see any widespread use of it.

--
Erik Wikström

Ioannis Vranos

unread,
Jan 20, 2008, 11:45:19 AM1/20/08
to


Perhaps a mechanism could be introduced in the C++0x/1x standard,
something simple like defining a function as:


void somefunc(void) throw()
{
// ...
}


and getting a compile time error saying something like:


"Error: void somefunc(void) throw(): Wrong exception specification.
somefunc can throw std::bad_alloc, std::range_error".

That is make the compiler to check exception specifications for errors too.

Erik Wikström

unread,
Jan 20, 2008, 12:11:57 PM1/20/08
to

Could be, but it would probably not work as well as you want. I am not
sure that it would work when calling functions that you do not have the
source for (i.e. there is not information about what exceptions can be
thrown in the binary).

--
Erik Wikström

Ioannis Vranos

unread,
Jan 20, 2008, 12:20:58 PM1/20/08
to
Erik Wikström wrote:
> somefunc can throw std::bad_alloc, std::range_error".
>>
>> That is make the compiler to check exception specifications for errors too.
>
> Could be, but it would probably not work as well as you want. I am not
> sure that it would work when calling functions that you do not have the
> source for (i.e. there is not information about what exceptions can be
> thrown in the binary).


Well, I suppose it could work for the source we have, in few words the
exception safety would be increased. An existing pre-built C++ library
could be revised to provide exception specifications at its next
release. That is, in the future the total exception safety would
increase, because the exception specification mechanism would finally
work (since now it doesn't work in practice as it is).

James Kanze

unread,
Jan 20, 2008, 1:52:57 PM1/20/08
to
On Jan 20, 12:39 pm, Erik Wikström <Erik-wikst...@telia.com> wrote:

[...]
> Section 14.6.1 [of TC++PL] starts by talking about checking of


> exception- specifications at compile-time and the paragraph
> after the quoted one says that the point is that you should
> not have to go through all your code and update your
> exception-specifications just because you make some change
> that allows more exceptions to be thrown.

Except that you have to do that anyway. If a function
guarantees that it will not throw any exceptions, or that it
will only throw X, then if it is changed to throw Y, the
contract has been changed, and all call sites must be
re-evaluated with respect to the new contract.

Realistically, of course, there's usually no point in
restricting which exceptions might be thrown by contract, at
least in most cases. So it would really only be relevant for
throw(). And realistically, there is a lot of code out there
which doesn't throw, and isn't declared throw(), so you
introducing compile time errors at this late date would only
break most existing code. (Note that when exceptions were
introduced into the language, none of the existing functions
threw, and none had an exception specification either.)

--
James Kanze (GABI Software) email:james...@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Bo Persson

unread,
Jan 20, 2008, 3:31:50 PM1/20/08
to

Yes, but you would get into real trouble if somefunc() calls some
templated functions, where one or two specializations might throw. How
is the compiler to know?


Bo Persson


Ioannis Vranos

unread,
Jan 20, 2008, 3:44:05 PM1/20/08
to
Ioannis Vranos wrote:
>
> Perhaps a mechanism could be introduced in the C++0x/1x standard,
> something simple like defining a function as:
>
>
> void somefunc(void) throw()
> {
> // ...
> }
>
>
> and getting a compile time error saying something like:
>
>
> "Error: void somefunc(void) throw(): Wrong exception specification.
> somefunc can throw std::bad_alloc, std::range_error".
>
> That is make the compiler to check exception specifications for errors too.


Some more details:


What I have in mind is "loose" application. That is, the compiler should
check only the available code accessible to it.


In addition, I think throw(void) should be equivalent to throw(), and
throw(...) should be equivalent to non-throw specification, e.g.:


// May throw anything.
void somefunc()
{
// ...
}


// May throw anything.
void somefunc() throw(...)
{
// ...
}


I think that even loose, the compile time checking of throw
specifications will improve the overall exception safety, and everyone
will usually know the exact types of exceptions he can catch on a given
call.


Any existing third-party, pre-built C++ library can be revised to

provide exception specifications at its next release. That is, in the

future the total exception safety will increase, because the exception
specification mechanism will finally work (since now I think it doesn't
work as it is provided, in practice).

Or that library can keep providing its facilities without exception
specifications or with the throw(...) equivalent ones.


If I may repeat, what I have in mind is "loose" application. That is,
the compiler should check only the available code accessible to it.


In the case of some function having the throw() specification, is using
indirectly code that may throw some exception, it can be flagged as a
compile-time error, provided that this source code that is used
indirectly by this function, is accessible to the compiler. Otherwise,
it will not be flagged as a compile-time error.

The run-time stuff of the throw specifications will still apply.

Ioannis Vranos

unread,
Jan 20, 2008, 4:13:24 PM1/20/08
to


Addition 2:

In this proposal, I think an opposite of the throw keyword may be
needed, to specify the exceptions that the compiler will ignore. I think
the right place of it, is the end of the function scope. An example:


void somefunc() throw()
{
std::vector<int> vec;

// ...

} nothrow(std::out_of_range)

Ioannis Vranos

unread,
Jan 20, 2008, 5:50:39 PM1/20/08
to

Some examples of these:


I.

void somefunc() throw(std::bad_alloc, my_app::graph_range_error)
{
// ...
} nothrow(std::out_of_range)

II. Equivalent cases:

void somefunc() throw()
{
// ...
} nothrow(std::bad_alloc)


void somefunc() throw(void)
{
// ...
} nothrow(std::bad_alloc)

III. Equivalent cases:

void somefunc()
{
// ...
}

void somefunc() throw(...)
{
// ...
}

void somefunc() throw(...)
{
// ...

} nothrow()


void somefunc()
{
//...
} nothrow()


void somefunc() throw(...)
{
// ...

} nothrow(void)


void somefunc()
{
//...
} nothrow(void)

Grizlyk

unread,
Jan 22, 2008, 12:03:16 AM1/22/08
to griz...@yandex.ru

Because of danger of often unpredictable runtime exit (with unexpected
or terminate), explicit declaration of exception is useless for
declaration of interfaces (member-function of classes).

I am not sure, but it seems to me, that standard is not require
concrete way of exception implementation, but do only that
void foo()throw(type);
will never return exception of not declared type.
Some compilers make "foo()throw();" even worse than "foo();", so
explicit declaration of exception for the compilers can be also
useless for the kind of function with "declared implementation", means
function, for which implementation will not be changed.

Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new

0 new messages