Best way to abuse exceptions

Pages: 12
Just thought I'd shared something amusing in Java.
https://gist.github.com/LB--/a5dfb3a47c155ac7690e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//For best effect, pipe stderr to a file
public class InfiniteException extends Throwable
{
	public static void main(String[] args) throws Throwable
	{
		throw new InfiniteException();
	}

	@Override
	public Throwable getCause()
	{
		return new InfiniteException();
	}
}
I guess it's good that the implementation used a recursive approach or this really would be infinite! (Note: it magically detects if you return this; instead)
Last edited on
Is it really an abuse if nothing is actually accomplished?
Pretend this was used in place of System.exit()
Do you mean you actually used this in code that's meant to do something useful?
No, it's just a though experiment.
Then why not just
1
2
3
4
5
6
7
8
9
//deep in the call stack
throw new ExitException();

/*...*/ main(/*...*/){
    try{
        dummy_main(/*...*/);
    }catch (ExitException){
    }
}
That's actually what Boost.coroutine does to give objects on the "fake" stack a chance to clean up when a coroutine object is destructed before the coroutine entry point has had a chance to return.
helios wrote:
...Boost.coroutine does [that] to give objects on the "fake" stack a chance to clean up when a coroutine object is destructed before the coroutine entry point has had a chance to return.


Some would call that... clever.
Last edited on
There isn't really any other way to unwind the stack while calling destructors.
Must be hard working in languages without RAII.
It's pretty amazing what you can do with Boost. There's a guy who used Boost.MPL to introduce a "code feature" concept that ensures e.g. functions marked as thread-safe can only call other functions marked as thread-safe.

http://www.artima.com/cppsource/codefeatures.html

It doesn't actually enforce thread-safety, though; they are just tag structures and they could be wrong.
@chrinsname: you can do that with std::tuple, it's just a design pattern and there's no real enforcement. Still clever though :)
Hey, you're right, you could use std::tuple (or boost::tuple in this case, since the article was written in 2008). Perhaps boost::mpl::vector has some other features.

It would be great to have a language feature that could enforce thread-and-exception-safety. I would also like the const specifier to be applicable to static-and-non-member functions (or perhaps a "pure" specifier [gcc has __attribute__((pure)) already]) which enforces that functions do not modify global state. It would make writing safe C++ functions more easy.
I have always wanted more -correctness in C++ than just const-correctness. Const-correctness alone is amazing and I am always missing it in other languages, but I frequently want to enforce other requirements and control which are convertible to others and how. Maybe in the far future when we get past Concepts Lite we can have some fun.
Haskell is good for that. In order to do anything with side-effects you have to use a monad, and it is enforced by the compiler e.g. if your function doesn't use the IO monad it can't use I/O, and it can't call any functions that do (unless you use the liftIO function, which lets you transform the IO monad to a different one).
I suppose that in a way, abstraction is really what we're doing, except that instead of abstracting using classes and objects, we're abstracting using functions and contracts. Am I right in thinking that? Or is it something else since, for example, const-correctness is viral?
Design-by-contract is usually not enforced by the compiler (although D does), what we're doing is like an abstracted but enforced version of DbC.

I have always wanted more -correctness in C++ than just const-correctness.


C++ doesn't have const-correctness. It has only half of it (meaning - you're not allowed to change the object but you're given no guarantee it cannot be changed by something else). Rust has full const-correctness.
Last edited on
Const-correctness is read-only-correctness, not unmodifiable-correctness.
I think this is a good demonstration:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

int i = 0;

void display_number(const int& x)
{
    using std::cout;
    using std::endl;

    cout<< "i = "<< x<< endl;
    i++;
    cout<< "i = "<< x<< endl;
}

int main(int c, char **v)
{
    display_number(i);
    return 0;
}
Last edited on
The function display_number() promises not to change the state of the program via its parameter. It may change the state of the program in any number of other ways, however.
Pages: 12