Re: [AD] 4.3 error handling |
[ Thread Index |
Date Index
| More lists.liballeg.org/allegro-developers Archives
]
On Wednesday 07 June 2006 14:32, Elias Pschernig wrote:
> True. We could even additionally provide a callback (NULL by default),
> but if you set one with al_set_error_callback, then it is gets called
> (and no longjmp-exception is raised).
Sounds reasonable. The user could always throw manually from the callback to
jump back to the last try/catch point.
> Yeah, this example makes more sense. Still, it won't occur often - an
> initialization as complicated as above only should be necessary if you
> do something special.
That is actual audio init code you'd use with the current sound code. Granted
it's the low-level stuff, but it's still what you'd do. And it'd only get
more complicated if you want to use muliple AL_VOICEs, or specific drivers,
or setting options, or whatever else.
> If you just want to use al_play_sample, then an
> al_init_audio() should be all that's needed (and therefore a simple if
> would be less code than the al_error_try {} al_error_catch {}).
For the high-level stuff, sure. But the low-level code still needs to be
called somewhere.
> > Then that's all you have to use. Just call al_error_disable_throws() and
> > do it the C way.
>
> Well, having to call al_error_disable_throws() for each program would
> not look favorably for the API to me.
Could always make an al_init flag to make throwing on or off by default. eg:
al_init(AL_INIT_ALL | AL_NO_ERR_JUMPS);
You could still enable or disable them manually after this point.
> Yes. In a way it is nice. I just have learned in the past to dislike any
> hackish (using setjmp/longjmp always is hackish, and #defines like this
> are so even more) features in C code.
I don't see setjmp/longjmp as hackish. But like any feature, you just need to
use it responsibly. In all honesty, I think this behavior is actually pretty
close to what C++ itself does, just with a few more extra features built into
the language.
> Yes, it shouldn't be a problem normally. A big danger I see is from
> something like:
Yes, but writing bad code is writing bad code. The library shouldn't be
responsible for the coder's sloppiness.
> Also this will go wrong in a bad way:
>
> int my_init(void)
> {
> al_error_catch {
> al_audio_init();
> }
> al_error_try {
>
> }
> return 0;
> }
That would actually give you a compile error. al_catch would put in a close
brace after calling to clear the last jump point, which would effectively
close the function. But it's still improper code, and improper code can give
you any range of problems (just look at C++ if you want to see errors that
aren't really indicative of the actual error).
> Hm, or:
>
> int my_init(void)
> {
> if (want_sound) {
> al_error_try
> al_audio_init();
> else
> printf("If you code python this one will happen to you :P\n");
> }
> }
>
> In all of those, the C compiler will not even warn.
That would, because al_try puts in its own open brace, and a matching al_catch
would put in the proper close brace, so the bracing would be left unbalanced
and the compiler would throw an error.
> Something else which might be a problem (probably it's not) - how well
> will setjmp/longjmp work when using other languages?
Depends on how closely the language uses Allegro's functions. If it's not
direct, then you can see the C++ wrapper example (replacing throw with
whatever error handling feature the language uses). If it's more direct, it'd
probably have to just disable throwing.
> Con:
> - Easy to make very non-obvious mistakes, as is the problem with
> many macros trying to add language features to C which it simply does
> not have.
I wouldn't say it's trying to add a feature C doesn't have. It's just using
features C has always had in a clever way. I'll concede the macros to make it
read like C++ *might* be a bit too much, but if that's the case, then it
could just be a bit less transparent. Something like:
if(al_error_test())
{
...code...
al_error_end_test();
}
else
{
...user error handling...
}
Effectively the same, and more obvious to what it's doing (and could make it a
bit easier since the user can call end_test() maually and return/jump/throw,
whatever, without consequence). But it can also lead to more coding error if
the user forgets to call end_test(), and you *won't* get a compile
warning/error about it. As well, al_error_test would still need to be a
macro, but it would simply be something like:
#define al_error_test() setjmp(*_al_error_next_jump_point())
The reason it has to be a macro is because you can't jump back to a function
which returned (so it has to be called directly).
> - C++ users can as well use a proper C++ wrapper, which can use real
> exceptions.
I don't see why this is a con. The code doesn't interfere with this (if
anything, it makes it easier).