views:

334

answers:

9

I'm programming C++ using the underscore naming style (as opposed to camel case) which is also used by the STL and boost. However, since both types and variables/functions are named all lower case, a member variable declaration as follows will lead to compiler errors (or at least trouble):

position position;

A member variable named position which is of type position. I don't know how else to name it: It's generally a position, but it is also the position of the object. In camel case, this would be fine with the compiler:

Position position;

But in C++ it causes problems. I don't want to switch to camel case, use Hungarian notation or add a trailing underscore because of that, so I'm wondering: Is it a good practice to name a member like a type anyways?

In C, it is pretty common to use cryptic one-letter variables for this:

int i;

But I find that a bit, well, cryptic:

position p;

Are there any rules of thumb for variable naming I can use to avoid this?

There are more examples in my code if you need something to work on:

mouse_over(entity entity) // Returns true if the mouse is over the entity

manager &manager; // A reference to the framework's manager

audio audio; // The audio subsystem

Edit:

I was curious to see if Bjarne Stroustrup himself has something to say on this issue. Apparently, he hasn't, but he suggests coding conventions that would work around my compiler problems:

For example, capitalize nonstandard library user-defined types and start nontypes with a lowercase letter

That'd be consistent with STL and boost, so I might use that. However, most of you agree that this naming should be avoided whether it compiles or not. So does Stroustrup:

it is unwise to choose names that differ only by capitalization.

+2  A: 

Yes, it is a bad practice. Variable names should be more specific if they have a long lifetime or important meaning (temporaries are ok). Remember that C++ is very strictly typed- you can't have a variable and not be very sure what it's type is. A variable Type type, for example, basically just means that it doesn't have a name.

DeadMG
+8  A: 

Giving a variable the same name as its type is almost always a bad idea, because it makes it very difficult to tell what code refers to the type and what code refers to the variable. For example, consider the following class:

struct position
{
    void operator()() { }
};

// later on, somewhere:
position position;

Now, if we see a line of code that uses:

position()

we can't readily tell whether that constructs a position object or calls position::operator()(). We have to go back and see whether there is an object named position currently in scope.

Naming conventions are a very touchy, subjective, and argumentative thing. I would just recommend picking one that distinguishes types from variables in some way. Personally, I choose to capitalize my types and leave my variables as starting with a lowercase letter.

It doesn't really matter how you distinguish them (your suggestions of using capitalization or a trailing underscore are both common), just so long as your usage is consistent.

James McNellis
+1  A: 

This is why I picked up the old MFC practice of prefixing member variables with m_, as in "m_position." A lot of the Java people would do "thePosition" for essentially the same reason, though if you pointed out the similarity at the time they'd turn funny colors and rant at you.

mjfgates
+5  A: 

The local meaning is rarely a good unique global description of the type:

cartesian_point_2d position;  // rectangular, not polar coordinates
mouse_over(ui_entity entity); // not a business layer entity
xyz_manager& manager;         // what's a manager without something to manage?
audio_system audio;
Ben Voigt
It's impressive how you could come up with sane suggestions for all of my examples like this. Did you use any rules of thumb or is it just something one learns with time? I'll sit down and think about each duplicate name carefully now.
Noarth
From experience, but that doesn't mean there aren't patterns you can apply. First, notice that in every case I changed the type name. That's because the variable has context, moreso than the type. Another way to add context with types is with namespaces. Then I tried to think of another application where the same word might be used but the type could not be, and added some distiguishing characteristic to the type name. For example, weather satellites also have position, which might be (latitude, longitude, altitude).
Ben Voigt
Please note that I'm still unhappy with `audio_system`, I picked that because that was your own comment about it, but I would prefer something like `pcm_audio_player` or `midi_audio_processor` or `wavfile_audio_recorder` that tells what type of audio and whether it records, plays, or modifies the audio stream.
Ben Voigt
Well, it's the audio subsystem of a game engine - audio_system is pretty good actually. The only thing I'm still unhappy with is "engine_manager" (that's what I called it) because it resides in the namespace "engine", it's name is: "engine:engine_manager" and that is a bit redundant.
Noarth
Then `game_engine::audio_mixer` and `game_engine::asset_manager` are sounding better to me. The original names just didn't carry enough information to make really good suggestions. The only "manager" in a game engine I can think of that shouldn't be broken down further is a `game_engine::class_factory`, other things might be `asset_manager` (which unpacks sounds/sprite images/textures/AI scripts from disk), `sprite_manager`, `memory_manager`, `saved_game_manager`, `window_manager`, etc and these are all different enough in responsibility to not belong in the same class.
Ben Voigt
If you can't describe the responsibilities of your `game_engine::manager` in under 20 words without using the term `engine` then there are probably several smaller leaner classes begging to come out during refactoring.
Ben Voigt
Well, the engine_manager basically just orchestrates the creation of the various systems. I did that because some code has to be executed before any system can be initialised and I didn't know where else to put it. I might call it "system_manager".
Noarth
Maybe `game_engine::startup`?
Ben Voigt
Hm, sounds good as well :) I think I'm slowly starting to develop some naming skills, thank you!
Noarth
+3  A: 

Naming variables after their type specifically is indeed a bad practice. The code is supposed to be as type-independent as possible. That implies that any references to actual types should be restricted to declarations (again, as much as possible). Trying to embed type information into variable name would violate that principle. Don't do it.

What one might want to embed into variable name is the variable's semantical meaning. Like "width", "length", "index", "coordinate", "rectangle", "color", "string", "converter" and so on. Unfortunately, many people, when they see it, incorrectly assume that these portions of the names are intended to describe the type of the variable. This misunderstanding often makes them to engage into that bad practice (of naming variables after their types) later in their code.

A classic well-known example of such misunderstanding is so called Hungarian notation. Hungarian notation implies prefixing variable names with special unified prefixes that describe the semantic of the variable. In this original form Hungarian notation is an extremely useful good naming convention. However, in many practical cases it gets distorted into something completely different: prefixing the variable names with something that describes their type. The latter is certainly not a good idea.

AndreyT
+1: I hate Hungarian notation and the whole `m_` nonsense.
John Dibling
@John: if you hate Hungarian notation, why give +1 to an answer which praises Hungarian notation? ;-)
Steve Jessop
A: 

Short and semi-wrong answer: If you have enough variables that you're working with in one place that you need non-cryptic variable names, maybe you have too many variables.

Though I actually disagree with that, to some extent. I think it has a grain of truth, but only that.

Some short variable names in C++ are just traditional and people know what they mean because they've been programming in C/C++ for awhile. Using i for an index variable is an example.

I think variable names should be named for their purpose. What's the position the position of? What's the manager managing? Why does this particular instance of the audio subsystem need to exist?

The trailing _ notation is used to distinguish member variable names. It can be very helpful when someone starts mentioning x out of nowhere to see x_ and know that it's coming from the class, and isn't declared in an enclosing scope or the global scope.

Omnifarious
IMO, short, cryptic names are okay for local variables and parameters. But member variables? I'm not sure if that wouldn't be confusing.
Noarth
@Noarth - And, apparently, my answer was confusing. Oh, well. :-)
Omnifarious
A: 

I have the same "problem" on a regular basis. I think it's a problem of abstration: In case of Position I'd suggest to abstract a bit more and introduce a type Point or something like that. Or specify what position is ment:

position mouse_pointer_pos;
Fair Dinkum Thinkum
A: 

You can just follow existing guidelines, e.g. Google's C++ style guide

It's good to be aware of naming being an important issue, but in my experience thinking too much about it is as harmful as not being aware of it.

I've experimented with Hungarian and didn't like it, most good programmers I know don't use it.

The main point I would make is it makes code less readable.

Dr. Jochen L. Leidner
The Google style guide is awful for modern C++ code.
GMan
+1  A: 

Personally, I capitalise my class names.

I disagree with, "it is unwise to choose names that differ only by capitalization", in this specific case. It's unwise to choose names which are confusingly similar. PoSItIoN and PoSiTIoN are confusingly similar. Position and position are not. Just make sure that when you search the code, you know and can control whether you're doing so case-sensitive or insensitive.

In cases where I have a function that only uses one variable of a particular type, then I might well name it after the type, since in English if something was, "the only position we're talking about", we'd refer to it as, "the position". Hence the variable name could reasonably be position.

Failing that, in your examples I might go with:

position pos;  // pretty sure people will realise I don't mean "positron".

mouse_over(entity target) // Returns true if the mouse is over the entity

manager &fmanager; // A reference to the framework's manager

devices::audio audio; // The audio subsystem
audio self; // "this" audio subsystem
audio audio_out; // The audio subsystem I'm configured to use for output

The last example is supposed to indicate that these problems might be solved by namespaces - outside the namespace in which audio is defined, you can safely refer to it as audio. Inside that namespace, functions operating on the audio subsystem frequently either are parts of the audio class interface which just happen to be free functions (in which case use conventions like self, other, lhs, rhs), or else are some kind of layered device or system which have an audio subsystem as a dependency (in which case, dependency for what purpose?).

entity and manager are terrible names for classes, by the way, since neither of them tells you anything about what the class represents. Every discrete thing is an "entity", and while not everything manages something else, "manage" is hopelessly vague.

Steve Jessop