Bjarne's comments about exception specification

G

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.
 
A

Alf P. Steinbach

* 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.

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


Cheers, & hth.,

- Alf
 
E

Erik Wikström

* 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.

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.
 
A

Alf P. Steinbach

* Erik Wikström:
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,

- Alf
 
I

Ioannis Vranos

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.
 
E

Erik Wikström

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.

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.
 
I

Ioannis Vranos

Erik said:
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.


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.
 
E

Erik Wikström

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.

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).
 
I

Ioannis Vranos

Erik said:
somefunc can throw std::bad_alloc, std::range_error".

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).
 
J

James Kanze

[...]
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.)
 
B

Bo Persson

Ioannis said:
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.

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
 
I

Ioannis Vranos

Ioannis said:
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.
 
I

Ioannis Vranos

Ioannis said:
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.


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::eek:ut_of_range)
 
I

Ioannis Vranos

Ioannis said:
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::eek:ut_of_range)



Some examples of these:


I.

void somefunc() throw(std::bad_alloc, my_app::graph_range_error)
{
// ...
} nothrow(std::eek:ut_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)
 
G

Grizlyk

Ioannis said:
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.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top