Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [C++] Good coding practices?

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
[C++] Good coding practices?
anonymous
Member #8025
November 2006

You could also have global functions instead of macros:

int white() { return makecol(255, 255, 255); }
int black() { return makecol(0, 0, 0); }

Practically no difference with how the macro works, except takes a bit more typing, but can be put in a namespace etc. The macro itself is benign, except perhaps for naming conflicts that they all can cause.

Arthur Kalliokoski
Second in Command
February 2005
avatar

I just use 0 and -1 for black and white :-X

They all watch too much MSNBC... they get ideas.

anonymous
Member #8025
November 2006

Except that is less readable, won't work on all colour depths and still doesn't solve the question what you do when you want other colours like green...

bamccaig
Member #7,536
July 2006
avatar

LennyLen said:

catch (std::runtime_error& e) {

Just for good measure, you might want to beef up the try...catch with a few more catches so no exceptions can get past your main routine. std::exception would catch any type derived from the standard exception type. And you can use an ellipsis (...) to catch anything else, and still output some kind of "WTF is this..." message so the user doesn't just have the game outright crash on him. In Intern's Quest, we catch std::invalid_argument, std::range_error, std::logic_error, std::runtime_error, and std::exception, in that order (clearly I didn't think ... was necessary at the time).

It allows for really sweet error handling in the application code. For starters, I just said everything is fatal, and would throw an exception for everything, which were only caught in main. It worked out really great because the game would typically output some kind of error message and exit gracefully for anything (Allegro complicated things because of how I was using timers, etc... Occasionally Allegro timers would not be uninstalled and would fire after Allegro was deinitialized and it would crash anyway, but I think that is mostly cleaned up now).

Speedo
Member #9,783
May 2008

bamccaig said:

Just for good measure, you might want to beef up the try...catch with a few more catches so no exceptions can get past your main routine. std::exception would catch any type derived from the standard exception type. And you can use an ellipsis (...) to catch anything else, and still output some kind of "WTF is this..." message so the user doesn't just have the game outright crash on him. In Intern's Quest, we catch std::invalid_argument, std::range_error, std::logic_error, std::runtime_error, and std::exception, in that order (clearly I didn't think ... was necessary at the time).

When you're just catching fatal errors in main, there's really not much point catching anything other than std::exception and any exceptions thrown by 3rd party libs which don't dervive from std::exception. Anything that derives from std::exception should adequately report whatever the problem was via its what() method, so there's no reason to catch derived types unless you're actually going to take some action specific to that type.

anonymous
Member #8025
November 2006

Speedo said:

unless you're actually going to take some action specific to that type

In which case you might also derive your own exception type for a particular error (e.g bitmap_load_error). Pick one of the stdexcepts as the base, and you'll only need a constructor that passes the exception message to the base constructor. It is also good to derive them from std exceptions, so you could always catch them with std::exception& if you don't want a particular action.

Speedo
Member #9,783
May 2008

anonymous said:

In which case you might also derive your own exception type for a particular error (e.g bitmap_load_error). Pick one of the stdexcepts as the base, and you'll only need a constructor that passes the exception message to the base constructor.

It's probably better to actually make your own intermediate exception type and then derive from it, because the standard doesn't require std::exception to be able to hold a message (MSVC and some other compilers extend it to do so, GCC doesn't).

I'd also recommend taking a look at Boost.Exception. It's particularly awesome in that you can transport any arbitrary information along with any given exception.

bamccaig
Member #7,536
July 2006
avatar

Though the type of exception does carry some information as well, which I found useful to display to the user as well. At least, I found it easier to guess what went wrong when debugging, without having to write type-specific what messages.

Speedo
Member #9,783
May 2008

IMO any exception should carry enough info to tell you (the programmer) what the problem was. But even if you want to display the name of the exception class, that's done easily enough with typeid(excpetionclass).name().

bamccaig
Member #7,536
July 2006
avatar

anonymous
Member #8025
November 2006

Speedo said:

It's probably better to actually make your own intermediate exception type and then derive from it, because the standard doesn't require std::exception to be able to hold a message (MSVC and some other compilers extend it to do so, GCC doesn't).

What I meant is use one of the derivates of the std::exception from <stdexcept> (IIRC std::exception itself doesn't even have a constructor to accept a message). Or naturally you can make your intermediary classes: std::exception > std::runtime_error > my::resource_error > my::bitmap_loading_error.

bamccaig said:

Though the type of exception does carry some information as well, which I found useful to display to the user as well. At least, I found it easier to guess what went wrong when debugging, without having to write type-specific what messages.

The type of the exception lets you catch different kinds of exceptions in different places and/or handle them separately. The what message is for a description that you fill in where the exception happens and where you have the exact information. You can also have intermediary try blocks where you catch the message, add more information to it and rethrow it (but I guess that would not be the general pattern and some things might better be left for the debugger).

 1   2   3 


Go to: