So, in the recent weeks I delved into C++ programming, and I programmed some things in SDL. Doing so, you always have to deal with a lot of (ugly) C++ code, which looks more like C than C++. One thing I noticed I when programming with SDL as opposed to college programming, that I do a lot of procedural programming. The reason for this is, that most sample SDL code I look at is structured like this, e.g.
bool init(…)
{
bool success = true;
thing_A = make_thing_A();
if (thing_A.is_valid() == false
{
success = false;
std::cout << "Something went wrong" << std::endl;
}
…
return success;
}
...like this. The cleanup would occur in the caller.
However this only works with functions, that don't need to return other variables otherwise. And this creates an ugly interface, where you never, if you can write something like if (!init())
, which makes you having to consult the documentation.
I never know if this is proper programming practice. Another approach would be to:
void init(…)
{
try
{
thing_A = make_thing_A();
if (thing_A.is_valid() == false
{
throw ;
}
…
catch (std::exception &e)
{
std::cout << "Something went wrong" << std::endl;
cleanup();
}
}
But then I read, I shouldn't put this try-catch-routine
into the function, but rather into the caller:
void init(…)
{
thing_A = make_thing_A();
if (thing_A.is_valid() == false
{
throw ;
}
}
int main(void)
{
try
{
init(…);
}
catch (std::exception &e)
{
std::cout << "Something went wrong" << std::endl;
cleanup();
}
}
At the moment this is my number one issue, when writing software, I just don't what to do. I think the cleanest solution is the second, because it encapsulates the complete logic into the callee and it implements DRY, because you don't have to put the cleanup logic into every caller. Is that right? I've never heard an absolute opinion on this.
EDIT: I'm not necessarily specifically talking about SDL2, but more generally. E.g. I know there is a consensus, that you should prefer std::unique_ptr
over std::auto_ptr
, but when dealing with error handling I see so many approaches: errno
, return values, exceptions, booleans, but I don't which one is the go-to approach, which one you should avoid, in which case it might be a good idea to do approach XYZ, etc.