Does Anyone Here Programme Without Using Literals??

This topic is 4857 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I have just started C++ in uni lectures and literals are bad practice apparently. ace

Share on other sites
Yes they are.

Consider this: You write code for your engine that assumes GeForce3 type hardware. You hard code:

for(int texturestage = 0; texturestage < 8; texturestage++)
{
}

and

LPDIRECT3DTEXTURE9 m_pTextures[4];

etc.etc.

This is all over your code... Hundreds, thousands, of places where you've put the number 8 and 4.

#define MAXTEXTURESTAGES 8
#define MAXTEXTURES 4
or
const int MAXTEXTURESTAGES = 8;
const int MAXTEXTURES = 4;

and then

for(int texturestage = 0; texturestage < MAXTEXTURESTAGES; texturestage++)
{
}

LPDIRECT3DTEXTURE9 m_pTextures[MAXTEXTURES];

Now, when you want to support different hardware, you change a few values in ONE place, recompile, and suddenly you're storing enough data, and the code is accessing it.

Share on other sites
Or even better still, make your engine completely data driven.

Share on other sites
data driven, like reading the numbers etc from a file? a script?

Share on other sites
Quote:
 Original post by ace_lovegrovedata driven, like reading the numbers etc from a file? a script?
Yes, like reading all variable quantities in from a file, especially an initialization file (or the registry).

Share on other sites
Yes, either really, though i generally think of scripts as files too. But DO NOT worry about that right now... programming something large scale is hard enough without making every stupid variable modified in a file, add that at the end if anything, its a great idea, but not essential.

-Dan

Share on other sites
Oh, ive already done some scripting, writing my own language etc, i have no problem with that sort of stuff. Was just wondering what the best way to do this is. :)

So having a settings file for the size of the window etc is best?

ace

Share on other sites
Quote:
 Original post by ace_lovegroveSo having a settings file for the size of the window etc is best?
Yes, but have an in-application interface for modifying those settings.

Share on other sites
Quote:
 Original post by ace_lovegrovedata driven, like reading the numbers etc from a file? a script?

Yes.

Often people keep data for limits and general configuration in .ini files and similar (xml is currently flavour of the month).

A big advantage is you don't need to rebuild your code to change limits etc, you simply edit data in a file.

Scripting and things like D3D .fx files is the next step in being data driven where you're actually moving logic and complex behaviour into data.

Being data driven is a good idea.

An example scenario would be the UI and text for your program:

- hardcoding everything as literals, you'd have the text and dimensions for buttons such as "Cancel" in the code repeated wherever you needed it, e.g.
button1.SetSizeAndLabel( 10, 10, "Cancel" );
button2.SetSizeAndLabel( 10, 10, "Ok" );
button3.SetSizeAndLabel( 10, 10, "Cancel" );

- putting all the constants in one place, the above would be re-written as:
#define CANCEL_WIDTH 10
#define CANCEL_HEIGHT 10
#define CANCEL_LABEL "Cancel"
...
button1.SetSizeAndLabel( CANCEL_WIDTH, CANCEL_HEIGHT, CANCEL_LABEL );
button2.SetSizeAndLabel( OK_WIDTH, OK_HEIGHT, OK_LABEL );
button3.SetSizeAndLabel( CANCEL_WIDTH, CANCEL_HEIGHT, CANCEL_LABEL );

- with a data driven approach, all those constants would be stored somewhere and read from a file, e.g.
struct UI_CONSTANTS{ u32 cancel_width, cancel_height; string cancel_label; ... string ok_label;}

...
...
button1.SetSizeAndLabel( ui.cancel_width, ui.cancel_height, ui.cancel_label );
...

Now imagine you want to localise your program for the German market, the text strings will be different, and often are much longer than the English equivilent so both the strings and button sizes will need to change. Consider the work involved with each approach:

- with literals you have to search all your source files for the values you need to replace, you'll usually always get some false matches too - so it usually ends up a very labour intensive manual job - not nice.

- with all the constants defined at the top of the module or even in a specific place it's much easier, but you still have to edit source files and rebuild the code.

- with data driven, all you need to do is edit data in a file, no rebuilds, less testing etc. Additionally if you use a common file format you could use an editor made for that file format.

Being data driven also makes it much easier to implement things like a debug console in a game (like the Quake console) - and for UI's it makes them easily skinnable (Longhorn is going that way with its XAML files too).

Back to literals:

- it's ok to use literals in places where you know for a fact that a value is never going to need changing. For example the number of rows and columns in a 4x4 matrix - you always *know* it's going to be 4. Another example would be the bits in a byte (NB: *NOT* the same as the number of bits in a "char" type).

- use "#define" or "const" in places where you know something isn't likely to change for a particular platform or is going to be a hard limit (maximum number of texture stages in a D3D version for example).

- use data driven wherever it makes sense - it tends to make sense a lot of the time.