Does Anyone Here Programme Without Using Literals??

Started by
7 comments, last by S1CA 19 years, 6 months ago
I have just started C++ in uni lectures and literals are bad practice apparently. ace
Advertisement
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.

instead go:

#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.
Or even better still, make your engine completely data driven.
data driven, like reading the numbers etc from a file? a script?
Quote:Original post by ace_lovegrove
data 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).
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
When General Patton died after World War 2 he went to the gates of Heaven to talk to St. Peter. The first thing he asked is if there were any Marines in heaven. St. Peter told him no, Marines are too rowdy for heaven. He then asked why Patton wanted to know. Patton told him he was sick of the Marines overshadowing the Army because they did more with less and were all hard-core sons of bitches. St. Peter reassured him there were no Marines so Patton went into Heaven. As he was checking out his new home he rounded a corner and saw someone in Marine Dress Blues. He ran back to St. Peter and yelled "You lied to me! There are Marines in heaven!" St. Peter said "Who him? That's just God. He wishes he were a Marine."
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
Quote:Original post by ace_lovegrove
So having a settings file for the size of the window etc is best?
Yes, but have an in-application interface for modifying those settings.
Quote:Original post by ace_lovegrove
data 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;}

...
read_values_from_file_and_fill_in_UI_CONSTANTS(...);
...
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.

Simon O'Connor | Technical Director (Newcastle) Lockwood Publishing | LinkedIn | Personal site

This topic is closed to new replies.

Advertisement