Sign in to follow this  

Prefixing names using some notation

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

Let's say we have this little convention of prefixing variable names, based on the kind of the variable:
prefix - meaning         (sample variable name)

p      - pointer         (pWindow)
c      - class or struct (cBox)
r      - reference       (rNode)
a      - array           (aObjects)
f      - real number     (fTime)
i      - integer         (iIndex)
n      - unsigned integer(nVertices) // usually used for count
What is the disadvantage of using such prefixes versus not using any prefixes for the variable names at all? For example if somewhere in someones code you'd see a cleverly named variable:
data
What can you say about it and how could you continue using it without looking up its declaration or looking around for other code using that same variable? If the variable was prefixed with p, you'd automatically know that it's a pointer, that you can write -> and hope that intellisense will show you a list of its members, and that you may be concerned by its life time (like make sure that it's destroyed somewhere appropriate using delete). If the variable was prefixed with a, you'd be aware that it's an array of some type, also that you may have to delete it using delete[]. If the variable was prefixed with c, you'd know that you may continue writing a . and see what intellisense has to offer, also that you shouldn't be concerned by its life time, since it will be destroyed when it goes out of scope. If the variable was prefixed with r, you'd know mostly the same stuff as if it was prefixed with c, except that you probably shouldn't be attempting to use the variable as a temporary, since you may overwrite some useful data somewhere outside your current scope. Another advantage of prefixing is that for example if you wrote fps = frameCount / ticks * 1000; you can't say for sure if the result in fps will be an integer or a real number (which you may be expecting), unless you know that at least one of variables frameCount or ticks is of real type. Having them prefixed with n, i or f saves you the time of going to see their declarations, or worse - getting only the integer quotient of the division during playtesting, while you may have expected to get a real value. If you happen to be working in a large function with a lot of different variables it's always easier to remember the kind of variable you currently need rather than its name, so you may just type in its prefix and select the variable you need from the intellisense list. While it's been said around the internet that variable names without prefixes are more readable, you're getting less information from its name and you will end up needing to look up the declaration of the variables in order to know what you must do with them which adds time to reading the code, also burdens your thinking by making you explicitly remember what kind each variable is.

Share this post


Link to post
Share on other sites
On the origins of species... um, Hungarian notation.


The rest of the arguments can be best explained with this code:
// MUST BE 7
const int MAX = 4;


Code changes. Hence variable names should reflect the function, not the form. Once a variable is referenced in 500 files, across 20 projects, renaming it simply isn't possible anymore.

Share this post


Link to post
Share on other sites
The variable isn't that likely to require a change of its kind, especially if it's already so widely spread. And even if it is inevitably needed to change the kind of the variable, it is likely that the name would have to be changed anyway.

Share this post


Link to post
Share on other sites
Quote:
Original post by Giedrius
saves you the time of going to see their declarations,


You mean the 0.2 second mouse-over tool-tip delay? Or the 0.2 second right-click -> go to declaration/definition?

Hungarian notation was useful in the past when IDE functionality was next to non-existent. Nowadays it only hinders development. If you don't believe me, start a project using Hungarian notation. Keep developing it and I guarantee you'll either forget to use Hungarian notation or get tired of it.

Share this post


Link to post
Share on other sites
It's more likely to take 0.2 seconds when there's a prefix. It still takes more time to roll over your mouse to see the tooltip or go to the declaration using your keyboard. And you may also forget the kind of the variable after a while. Having it in the prefix may give you information at a simple glance.

Share this post


Link to post
Share on other sites
You shouldn't prefix it with a type meaning, but rather with a usage meaning. For example: it's a data member, its an input / output variable for a function, it's temporary etc...

If you don't know the type, or the kind-of-type, without a prefix, you should seriously consider to refactor the code.

Share this post


Link to post
Share on other sites
Quote:
Original post by Giedrius
The variable isn't that likely to require a change of its kind, especially if it's already so widely spread.


Real world experience says otherwise.

Quote:
And even if it is inevitably needed to change the kind of the variable, it is likely that the name would have to be changed anyway.

Which works great for a hobby project.

In practice, there will be multiple projects, each having dozens of branches, features back-ported, released DLLs in use by potentially millions of customers, all referencing same names, needing to support 5 year old files that have passed end of life, ....

API/interface is the single most expensive thing to change. This is why most APIs in heavy use are not updated, but deprecated, while features are always only added, never removed (looking at you Java).

Same goes for WinAPI. Layer upon layer of new concepts, but nothing ever removed.


And another C/C++ gotcha:
int i = (int)pFoo;

pFoo is pointer to foo, pointers are 32 bit, int is 32 bit. Works fine.

Except that Microsoft had to release extra training documents to discuss how all applications had to be patched, since pFoo was no longer same as pFoo, even if used in same application. Some of pFoos were now 64 bit, while others were 32 bit. Some were even 16 bit.


And while this could be fixed via p32Foo and p64Foo, it breaks elsewhere. Pointers need to be natively sized, so naming them p32 and p64 doesn't make sense - they will be whatever platform they are built on.

wchar_t - how many bytes? wstrlen expects wchar_t, yet size of wchar_t is up to compiler, so p2bwct (pointer to 2 byte wchar_t) isn't compatible with p4bwct (pointer to 4 byte wchar_t).


Hungarian notation has been proven as a falacy. The article linked before discusses on why the wrong one got adopted.

Share this post


Link to post
Share on other sites
I use pVar for pointers and mVar for members. I'll also sometimes use oVar to signify "out" parameters to functions.

Other than that I think prefixes are pretty useless. Even the ones I use are mostly out of habit rather than practical necessity.

Share this post


Link to post
Share on other sites
Quote:
Original post by Decrius
If you don't know the type, or the kind-of-type, without a prefix, you should seriously consider to refactor the code.

For example if you'd have a variable named "diffuseTexture", there's no way to change its name so that you may know without looking at its declaration whether it's a pointer, an object, a reference, or maybe an enum or something else.

I personally find it easier to read or write code if I have such information available without having to explicitly look it up.


So the main reason for not using these prefixes is that some extremely widespread variable might need its type changed?

Share this post


Link to post
Share on other sites
Quote:
Original post by Giedrius
For example if you'd have a variable named "diffuseTexture", there's no way to change its name so that you may know without looking at its declaration whether it's a pointer, an object, a reference, or maybe an enum or something else.


Why does it matter? If it's just about the . vs ->, VAX will actively fix your typos [grin]

The reason your argument is invalid is because you never end up in some random function, with some random variable that you have absolutely no preexisting knowledge about, and actually having to use that variable. If you are using the variable, then you will already know its type, and, if not, the mouse-over tool-tip will tell you.

Share this post


Link to post
Share on other sites
Personaly, and although I think Microsoft's "systems" hungarian is retarded, I don't so much have a problem with the scheme you've outlined. It seems simple enough, concise, and avoids being so terribly specific (which is the fault with Microsoft's Hungarian) if its what you really want to do -- its your code after all, so if it helps *YOU* and *YOUR TEAM*, then all other oppinions be damned as long as you're willing to live with the consequences, both good and bad.


I regularly use 'm', 's' and 'g' prefixs to denote scope (member, static (class), and global, respectively) as I find that hinting the scope gives me information that intellisense doesn't always, at least with a simple mouse-over.

'p' and 'r' I could maybe see myself using (although I don't, since intellisense will tell me this), as I could tell at a glance whether calls against said object affect a long-lived object that is referenced.

I don't see a point to 'c', but if you're inclined to keep it I might suggest 't' instead, for 'type', which is perhaps more nuetral (presuming you didn't want to reserve that prefix for typedefs, but its probably a bad idea to call out typedefs in this way anyhow, as that goes to 'form rather than function'.

I usually use the rule that arrays are pluralized, so adding an 'a' would be redundant for me.

Your use of 'f' and 'i' aren't my cup of tea (again, because intellisense already tells me this stuff easily), but they're probably neutral and non-specific enough to be egregiously annoying, and migrating from Integers to Reals (or vice-versa) is rare (as opposed to say float to double or char to short, which wouldn't affect the naming scheme) -- in short, you can argue that this is closer to function than form, if you squint at it a little. That said, I'd probably distinguish between signed and unsigned ('s' and 'u') integers, as well as booleans ('b'), if you're going to have this sort of arrangement at all. I'd prefer 'r' over 'f' for real values if it weren't already taken, and I can't think of a substitute prefix for references.

This last part leaves us with what to do with your 'n' -- and I say keep it, but use it only for counters since that represents additional useful information to what intellisense gives you. I'd want a distinct prefix 'u' for unsigned values which are not counters (if I were so inclined) -- say a "volume" variable, which (probably) shouldn't be able to go negative, but isn't a 'counting' variable in any way.


Personally, I find that my scope-based prefixes, combined with literate programming (I consult Thesaurus.com not-infrequently when programming) and a few other conventions: arrays have plural names, boolean values and functions begin with an assertive "helping" verb like 'is' or 'has' (perhaps these could be called 'stateful' verbs) really serve my needs quite well, so I don't really embelish beyond that.

Other prefixes might be more useful, as in the original meaning of hungarian notation -- its certainly not a bad use of prefixation, but I prefer longer, more literal variable names.

Share this post


Link to post
Share on other sites
Quote:
Original post by Giedrius
So the main reason for not using these prefixes is that some extremely widespread variable might need its type changed?


I have another. TMI! (Too Much Information)

Simply put: I don't need to know what exact type a variable is, that's a compiler problem! Unnecessary information is a distraction, thus a waste of energy. That alone is enough, for me.

I like what Antheus said:
Quote:
...variable names should reflect the function, not the form.


If i have a variable, it's type should be implicate by the name. While the exact type may not be, its general abilities should still be obvious.

But, i don't really like the Hungarian notation expressed in Antheus's link since it adds prerequisite knowledge to interpreting the code. (For example, i think it's a bad thing that a programmer has to learn that us = unsafe string in the article.) Abbreviations just create more abstractions that have to be managed. I think the purposes of variables can be expressed without them.

PS: I program without an IDE. I do not have a tool-tip or whatever. I still find Hungarian notation in every form unnecessary.

Share this post


Link to post
Share on other sites
Quote:
I personally find it easier to read or write code if I have such information available without having to explicitly look it up.
Well, it sounds like your mind is already made up, more or less. For what it's worth though, I'll go ahead and throw in another vote for not using Hungarian (or other similar naming schemes).
Quote:
So the main reason for not using these prefixes is that some extremely widespread variable might need its type changed?
In well-structured code, I would imagine 'extremely widespread variables' would be relatively rare. Still, Antheus' example:
Quote:
// MUST BE 7

const int MAX = 4;
Remains relevant, I think.

The type of a variable (which seems to be what we're talking about here) is inherent to that variable. If you incorporate the type into the variable name, you now have two pieces of information, both describing the same property of the variable, that must be kept in sync manually.

To me, this alone is enough reason to avoid such naming conventions. IMO, redundancy in code is best avoided where possible, and anything that has to be kept in sync manually - a comment as in Antheus' example, an enumeration whose value is dependent on that of a previous enumeration, etc. - is burdensome and has the potential for falling out of sync and therefore becoming meaningless at best, and outright misleading and incorrect at worst.

I also find code that uses such naming schemes difficult and tiresome to read. Personally, I like code to read like a narrative, and I find:
The prince rode off on the horse.
Much easier to read than:
aThe nPrince vRode aOff pOn aThe nHorse.
Which is what Hungarian (of the type we're talking about) looks like to me.

Share this post


Link to post
Share on other sites
I once had to maintain a piece of software (a hardware driver written in FORTRAN) in which all variable names were prefixed with the letter 'o'.

I learned much from that exercise.

What prefix would you use for a reference to an array of doubles?

Share this post


Link to post
Share on other sites
Quote:
Original post by Giedrius
So the main reason for not using these prefixes is that some extremely widespread variable might need its type changed?

The main reason for not using them is that they're ugly, unnecessary, make code harder to read, make code harder to update, and inevitably get out of sync with reality.

They made some sense in ancient versions of C that had little to no type checking. Or perhaps in assembly code for the same reason. Those days are largely gone.

I still use prefixes for member variables but this is an issue of scope, not type. Even then there are other ways (e.g. in C++ you can do this->foo instead of m_foo). I was a holdout on pointers for a while but eventually decided that -> vs . is a trivial distinction readily apparent from surrounding code and even if I got it wrong the compiler would tell me. I held out even longer on pointers-to-pointers but found that I needed them less and less often as I embraced exceptions.

The bit about "even if I got it wrong the compiler would tell me" is the important bit. Hungarian arose largely because the compiler would not tell you so anything that helped you avoid type conflicts was something that helped you not ship bugs. This isn't the 80's anymore. The compiler will tell you the vast majority of time if you get it wrong.

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquaredYou mean the 0.2 second mouse-over tool-tip delay? Or the 0.2 second right-click -> go to declaration/definition?

Hungarian notation was useful in the past when IDE functionality was next to non-existent. Nowadays it only hinders development. If you don't believe me, start a project using Hungarian notation. Keep developing it and I guarantee you'll either forget to use Hungarian notation or get tired of it.

As mentioned before you simply overstated the ease of looking up variable types to make your side seem stronger, but my reply is more about some guarantees you have erroneously made.

I started a very large project (L. Spiro Engine) with over 500 files and 250 classes/structures/etc., all written from scratch by myself.
Every single member, parameter, local, etc., is named with a very strict naming convention essentially Hungarian.
The next 500 files will also follow this convention 100% strictly and I will not forget nor get tired of it.



#1:
Rather than supporting any specific naming convention, I rather detest having no naming convention.
In another example posted by nullsquared he mentions ending up in a random function without pre-existing knowledge etc.
Well this is simply false to the Nth degree, at least if you actually code for a living.
I frequently have to view others’ code and find myself in functions I do not recognize, trying to understand a system designed by someone else.
In these cases, nothing pisses me off more than not being to immediately recognize the types and scopes of the variables I am seeing.
Types of variables are only one problem, but it is frustrating seeing a value being used and not immediately knowing whether it is a local, a parameter, a member, or, God forbid, a global.

And it is not just about being able to quickly identify the type/scope of variables you have already spotted.
If members were clearly marked m_*, I could easily scan the code and spot lines where the class itself is being modified. Being able to do this often allows one to focus just on code in one region of the function, rather than having to scan the whole function line-by-line.

If I want to quickly find places where a certain variable is accessed or modified, and if that variable happens to begin with _* (due to being a parameter) or m_* (member) or g_* (global), I am in luck. These prefixes are easier to spot on quick scans and makes for much easier data tracking.



#2:
But what is more annoying in a general sense is inconsistency. If you are going to use a style, use it throughout your code. No one can trust your code/naming conventions if you forget things or make mistakes. Even the Windows® API has problems with this.



#3:
Type data can be tricker than you think.
In the field of 3D math you will be using vectors and reals frequently, and you will encounter overloaded operators.
Cross products return vectors while dot products return reals (usually float).
But not everyone overloads vector operators the same way, and even if they did, the overloaded operators themselves often ambiguate the code, along with misleading names.

final = ballVel * dir;

dir is surely a vector, but is this vector DOT vector, vector CROSS vector, or float TIMES vector??
Perhaps this would make each case clearer:

fFinal = vBallVel * vDir; // Overloaded * must be DOT, since this returns a float.

vFinal = vBallVel * vDir; // Overloaded * must be CROSS since this returns a vector.

vFinal = fBallVel * vDir; // Overloaded * is just multiplication, and this is scaling a vector by a real.




Why even argue that naming conventions do not make code clearer? It always seems to me that lack of some naming convention or other just causes headaches and no gain, except that the one guy (or girl) who writes the code can be a bit lazier, deferring the headache to the unlucky fellows who must later read his or her code.
What kind of person knowingly writes ambiguous hard-to-understand-at-a-glance code and justifies it by telling others to waste time following tooltips, right-click to find definitions, and jump back and forth between windows?
Isn’t programming already a tricky business enough? What logic tells one not to add all the clarity possible even if just a little?

Point in case: Pick a convention. It doesn’t matter which one, but it should be one that attempts to give as much information as possible about the code you are writing. “Ugly” or not is not a factor when there are so many problems and consequences with hard-to-read code these days.


L. Spiro

Share this post


Link to post
Share on other sites
I find it handy to prefix stuff to a small degree as it makes naming more consistant

Data
pData // pointer to Data


Whatever convention makes it easy to remember is great

HOWEVER,

Full blown Hungarian is a poor way to name stuff IMHO.


Share this post


Link to post
Share on other sites
Just a couple of comments, for the sake of discussion.
Quote:
Types of variables are only one problem, but it is frustrating seeing a value being used and not immediately knowing whether it is a local, a parameter, a member, or, God forbid, a global.

And it is not just about being able to quickly identify the type/scope of variables you have already spotted.
If members were clearly marked m_*, I could easily scan the code and spot lines where the class itself is being modified. Being able to do this often allows one to focus just on code in one region of the function, rather than having to scan the whole function line-by-line.

If I want to quickly find places where a certain variable is accessed or modified, and if that variable happens to begin with _* (due to being a parameter) or m_* (member) or g_* (global), I am in luck. These prefixes are easier to spot on quick scans and makes for much easier data tracking.
For what it's worth, I think most of the discussion here has been related to type prefixes rather than scope prefixes/suffixes.

I still use m_ prefixes in my code, for the very reason you mention above. However, others on these forums have made compelling arguments for dropping even scope prefixes, and if I were to start a new code base from scratch, I might try going without them.
Quote:
Type data can be tricker than you think.
In the field of 3D math you will be using vectors and reals frequently, and you will encounter overloaded operators.
Cross products return vectors while dot products return reals (usually float).
But not everyone overloads vector operators the same way, and even if they did, the overloaded operators themselves often ambiguate the code, along with misleading names.

final = ballVel * dir;

dir is surely a vector, but is this vector DOT vector, vector CROSS vector, or float TIMES vector??
Perhaps this would make each case clearer:

fFinal = vBallVel * vDir; // Overloaded * must be DOT, since this returns a float.

vFinal = vBallVel * vDir; // Overloaded * must be CROSS since this returns a vector.

vFinal = fBallVel * vDir; // Overloaded * is just multiplication, and this is scaling a vector by a real.
That's an argument against ambiguous operator overloading, not an argument for type prefixes.

Many (including myself) would argue that overloading the * operator for the dot, cross, or member-wise product is a bad idea, for this very reason. Using named functions for these operators clears up any ambiguity and obviates the need for explanatory comments or type prefixes (in this context at least).
Quote:
Why even argue that naming conventions do not make code clearer?
We're not arguing that naming conventions don't make code clearer. We're just arguing as to whether Hungarian-style naming conventions make code clearer.
Quote:
It always seems to me that lack of some naming convention or other just causes headaches and no gain, except that the one guy (or girl) who writes the code can be a bit lazier, deferring the headache to the unlucky fellows who must later read his or her code.
For what it's worth, I've read and analyzed a lot of other people's code, and I always prefer reading code that doesn't use Hungarian-like notation.
Quote:
What kind of person knowingly writes ambiguous hard-to-understand-at-a-glance code and justifies it by telling others to waste time following tooltips, right-click to find definitions, and jump back and forth between windows?
Code without type prefixes needn't be ambiguous or hard to understand. In fact, with good variable names and good code structure, it can be quite clear and easy to read.
Quote:
What logic tells one not to add all the clarity possible even if just a little?
I prefer to take the approach of stripping away noise and redundant information until the code is as clean and straightforward as possible while still being clear and readable. (Or, to paraphrase Einstein, until the code is as 'simple as possible, but not simpler'.)

In any case, I don't think you can reasonably argue that Hungarian notation (of the type under discussion here) is 'the' right way to do things. Obviously it works for you, but it's equally clear that not everyone likes it, and that good code (even for large projects of the kind you described) can be written without it.

Share this post


Link to post
Share on other sites
I’m not for Hungarian (I just use my own derivative of it), but rather for any naming convention that tries to give at-a-glance information, hopefully useful.

Most of the discussions have been about type, but I think the original poster was open to any high/low points to each style.
And usually type information is not so hard to guess, but scoping is trickier. I think this is something else to consider when thinking about what a naming convention should convey, but it rarely gets mentioned, so I wanted to bring it up.

It seems the main difference between our views is that mine assume the author of the code is inconsistent, not necessarily using the best coding practices, etc., whereas yours assume the author is adding lots of comments, using decent coding structure, etc.
It may just be my own experience, but I tend to find code written in the former more often than in the latter. To be honest, I am not so creative as to have made up my previous examples; they came from actual experiences I have had repeatedly enough (at work) that I remember those cases all-too-well.

If you are lucky enough to be surrounded by reliable coders, maybe naming conventions are not as necessary.
But in my experience, most programmers are not reliable, and at least some confusion can be cleared up through naming conventions.
If naming prefixes are hard to read it just means you haven’t read much of it.



And while it is on my mind, another example of naming-convention helpfulness: 64-bit portability and other 64-bit issues.
These days my types include size.
LSUINT32 ui32Value;

This may hurt some eyes (but that really doesn’t matter when code is about functionality).
This has made a lot of code easier to manage when size information, not just type information, is valuable. Overflows and other issues become quite easy to find when I have type and size information at a glance on every variable.
Without a naming convention, you are asked, on top of the headache of following the code to find bugs, to keep a dictionary in your head as to what the types (and sizes) of each variable are. And when you originally checked the type of “varX”, you may have not have paid close attention to its size, unknowning that that would be a key factor to a bug later in the code.

Anyway, as I said, you have to decide if naming conventions are for you or not. But if you pick one, stick with it, reliably.


L. Spiro

Share this post


Link to post
Share on other sites
Quote:
Original post by YogurtEmperor
#3:
Type data can be tricker than you think.
In the field of 3D math you will be using vectors and reals frequently, and you will encounter overloaded operators.
Cross products return vectors while dot products return reals (usually float).
But not everyone overloads vector operators the same way, and even if they did, the overloaded operators themselves often ambiguate the code, along with misleading names.
final = ballVel * dir;

dir is surely a vector, but is this vector DOT vector, vector CROSS vector, or float TIMES vector??
Perhaps this would make each case clearer:
fFinal = vBallVel * vDir; // Overloaded * must be DOT, since this returns a float.
vFinal = vBallVel * vDir; // Overloaded * must be CROSS since this returns a vector.
vFinal = fBallVel * vDir; // Overloaded * is just multiplication, and this is scaling a vector by a real.

Or:

final = ballVel.Dot(dir);
final = ballVel.Cross(dir);
final = ballVel * dir;


And this way I don't have to backwards-deduce the nature of the operation by means of its return type. The only place where ambiguity might arise is in the last line (where ballVel could be either a float or a vector), but this is easily fixed by properly naming the variable:

final = ballSpeed * dir.

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
Quote:
Original post by Giedrius
saves you the time of going to see their declarations,


You mean the 0.2 second mouse-over tool-tip delay? Or the 0.2 second right-click -> go to declaration/definition?


Sorry for the late reply. If you know the right keystrokes (for me F12 under MSVC (at work!), F2 in QtCreator, e.g.), it is just 0.036 seconds.

Share this post


Link to post
Share on other sites
Quote:
Original post by AristeOr:

final = ballVel.Dot(dir);
final = ballVel.Cross(dir);
final = ballVel * dir;


And this way I don't have to backwards-deduce the nature of the operation by means of its return type. The only place where ambiguity might arise is in the last line (where ballVel could be either a float or a vector), but this is easily fixed by properly naming the variable:

final = ballSpeed * dir.

Speed vs. velocity is exactly what I meant by misleading names.
Basically, the problem boils down to people not being reliable. You can’t trust them to write meaningful names, lots of comments, non-ambiguous code, etc.
These are real-world examples that people commonly do, like it or not.

Even with naming conventions, people will be unreliable and make mistakes, but naming conventions are concrete in that the “what to do” can be clearly and explicitly defined. That is, “use meaningful and non-misleading names on variables” is a lot harder to follow than, “put a ‘p’ in front of pointers”. Aside from “misleading” being a relative term, some people simply don’t know about or think about the differences between “speed” and “velocity”.
If a person is likely to make mistakes on simply following a naming convention, he or she is probably more likely to also make mistakes related to improper naming, ambiguous overloading, etc.
Combine these mistakes with no naming conventions for a brew that will knock you off your feet in seconds.


L. Spiro

Share this post


Link to post
Share on other sites
Quote:
Original post by YogurtEmperor
fFinal = vBallVel * vDir;

vFinal = vBallVel * vDir;

vFinal = fBallVel * vDir;



I still don't know what the hell is final.
Also, in the third case fBallVel is disinforming. It should be fBallSpeed.
I personally prefer:
whateverTheHellThisBe = ballVelocity * direction;

whateverTheHellThisBe = ballSpeed * direction;

I even find direction a bit vague. I guess this appreciation would depend on context.

Share this post


Link to post
Share on other sites
Quote:
Original post by YogurtEmperor
nothing pisses me off more than not being to immediately recognize the types and scopes of the variables I am seeing.
Types of variables are only one problem, but it is frustrating seeing a value being used and not immediately knowing whether it is a local, a parameter, a member, or, God forbid, a global.

If you cannot tell immediately whether a variable is local to the function, you have a problem: the function is too big. If it does not fit on one screen, it is too big. It does too much. Split it up. I would even argue that functions with more than 10 lines are too big.

Same with classes. If your class has more than, say, 100 lines, it is too big. Remember the single-responsibility principle. Let your class do exactly one thing. If it does multiple things, split it up.

By the way, modern IDEs such as Eclipse display differently scoped variables differently.

Quote:
Original post by YogurtEmperor
If members were clearly marked m_*, I could easily scan the code and spot lines where the class itself is being modified.

Every method that is not marked as const is modifying your member variables. That's the whole point of encapsulation. If this is not the case, refactor. Utility functions do not belong in classes.

Quote:
Original post by YogurtEmperor
If I want to quickly find places where a certain variable is accessed or modified

I simply click on it, and Eclipse will automatically highlight each occurrence of the variable.

Quote:
Original post by YogurtEmperor
Why even argue that naming conventions do not make code clearer?

Because clean code should read like prose. That's what humans understand best. You should choose good names that speak for themselves. That's way more important than distracting prefixes.

Share this post


Link to post
Share on other sites
Quote:
Original post by DevFred
If you cannot tell immediately whether a variable is local to the function, you have a problem: the function is too big. If it does not fit on one screen, it is too big. It does too much. Split it up. I would even argue that functions with more than 10 lines are too big.

Same with classes. If your class has more than, say, 100 lines, it is too big. Remember the single-responsibility principle. Let your class do exactly one thing. If it does multiple things, split it up.

By the way, modern IDEs such as Eclipse display differently scoped variables differently.


That's totally valid when writing new code and you're responsible for that code. It's a completely different issue when you're dealing with Somebody Else's Code well after they've written it. TheDailyWTF is full of such examples :)

Case in point, I am currently porting a *massive* codebase to Android Native. Eclipse point-blank refuses to do anything but the basic syntax highlighting. I am, not kidding, minus any form of intellisense. For example, to find a variable's declaration I have to search the entire codebase using regex based on what I think the type of the variable is.

Oh, and did I mention there are several "key" files in this project that measures around 20k lines, each? One particular function gives me hand cramps every time I scroll through it. It takes about 30 seconds to compile just that one file :(

Luckily the developer used 'm' to designate scope, unluckily he used it inconsistently. Sometimes it means a local variable, sometimes it means a class variable, sometimes it's a global. More often than not it's a class variable but I can't count on it.

Anyway, the point is, if you have a programmer that insists on writing monolithic functions / classes / files, at least enforce a coding convention that will at least help folks without any good tools to navigate the code :P

Share this post


Link to post
Share on other sites

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

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this