Hi, my name is Alex...and I use bad variable names. ''[crowd:] Hi, Alex.'' Back in the day, while fresh out of college and wet behind the ears in the programming world, I used to name some variables very badly. The worst of which was my counter variable names. I now use i, j, k, and so on for local counts and things like activeRowCount for the more descriptive names. Before, in the early years mind you, it shames me to say, I would name my counters things like Dracula, Chocula, MonteChristo. They are all counts after all. I apologize for my intial variable naming conventions and shall go beat my face now as punishment. -- Alex typedef int count; ''Don't use i, j, and k for iterators! Use ii, jj, kk. Convention is still honored, yet searchability is increased by a million percent. The vars i, j, and k are BadVariableNames too!'' [Why would you ever search for an iterator like i, j or k? If you might ever need to search for a variable then give it a unique name.] If your tools cannot search for single character variables, the problem is with your tools, not with the millions of lines of code and the thousands of programmers that have had no such problem. -- AdamBerger Also, if you have to search for an iterator, you have bigger problems. The scope of such an iterator should be only a few lines anyway. -- DougKing ''Um, that's the point of this pattern! Many times, programmers have to work under less than ideal situations. Sometimes nice developtment tools simply aren't available. On other occasions, old extremely simple or poorly designed programs have to be maintained or extended. The pattern, which I recommended, has a low cost, yet provides a useful safety net for future development. I'm also not the first to use this convention; I learned it from...'' ''http://www.google.com/search?q=unmainnaming.html'' ''...and a quick google search shows many people also use it. -- Jimmy Cerra'' None of that makes it a better pattern. The item about the scope being a few lines still applies. Any decent computer has vi: /\ (notepad can search for whole words only too) or some similarly powerful editor. ''Old poorly designed programs are also less likely to have the suggested ii, jj, kk, variable names to begin with anyway.'' ---- For an argument in favor of "bad" variable names, see the badly-named IsWeird. ---- 'I recall a programmer who used to work for me who named variables "pig", "cow", "dog" ...' Some of the worst I've seen are using the lowercase "ell" and uppercase "oh" as variables: l = l + 1; This = That + O; A PetPeeve of mine was someone I worked with who liked to name miscellaneous C character arrays "mystring". Was he afraid that someone else would come along and misuse his variable? (I think that misuse is much less likely if you give them a clue as to what the variable's *FOR*!) ''Perhaps a habit derived from using the 'my' operator in PerlLanguage? -- DominicCronin'' A good variable name should indicate its use, like "Error''''''Message" or "Input''''''Buffer". And if it has several different uses, you should probably split it up into several different variables. I couldn't believe this one: "Information" - duuhhh, so that's what it's for(!) ''I have a class called Codes. It has a property called data. Guess what its type is... - that's right! CodeData -- DorKleiman'' Warning: NIL != NULL error on line 567 ^ Cannot assign NULL to NIL listener ---- Java and JavaBeans classics: * Foo''''''Data * Foo''''''Manager (interface) implemented by FooManagerI''''''mpl * getInfo() * setData() * Info''''''Bean * AbstractDataB''''''ean ---- ''A pet peeve of mine was someone I worked with who liked to name miscellaneous C character arrays "mystring".'' I am working on a project right now, where I have taken over someone else's Java code. It often goes something like this: public class Foo { private String myString; public Foo(String theString) { myString = theString; int aPos1 = 0; int aPos2; // ... } } i.e., the prefixes my, the and a are used a lot. Perhaps it is some kind of HungarianNotation? :) ''This is similar to UncleBobsNamingConventions. It takes some getting used to, but it can help make code read more like prose and disambiguate scopes.'' I am a newcomer to Smalltalk, and I have come across the 'a' prefix as a standard idiom, to mean an instance of a class of objects. I have not see 'the' or 'my' and I don't think they would be meaningful: instance variable names begin in lowercase, and class variable names in upper case letter: so Smalltalkers don't seem to see the need to confuse things further with 'the' and 'my'. ---- We are currently attempting to correct a number of serious problems in a particular component of a large C++ system. We found the following declaration in one of the files: const int TWENTY_EIGHT = 28; What in God's name were they thinking??? -- ChuckMcCorvey ''The problem here is that you assume they were'' '''thinking!''' ;-> [Maybe they wanted to support other values of 28?] At a past company, the coding standards forbid using MagicNumber''''''s. We ran a tool that counted coding standards violations, and we included that value in our team status reports. I ended up defining FOUR = 4, etc., since I didn't have the time to enter meaningful names. Maybe it was a descendent of an old UNIVAC program or by an old UNIVAC programmer? Twenty eight was the number of words per sector in old UNIVAC disk hardware and it lives on to this day. See http://www.fourmilab.ch/documents/univac/fastrand.html#28 (new speaker here) I actually did something very similar a year ago, to circumvent what seems to be a bug in the Microsoft C 5.1 compiler. While porting some code implementing the AdvancedEncryptionStandard algorithm to a legacy DOS environment (!) I found the compiler choking on shifting certain values 8 bits to the right. ''But only when the literal digit 8 was used.'' So I globally replaced >> 8 with >> EIGHT and put const int EIGHT = 8; at the top of the program. It worked great. Passed all unit tests. For some reason I don't think Microsoft will fix this particular bug, if indeed it is one. I am not making this up. -- MarkSchumann ---- #define ONE 1 #define ZERO 0 No, I'm not kidding. I'm glad I didn't have to work on it. -- RobCrawford ''At least it wasn't the following:'' #define ONE 0 #define ZERO 1 ---- Weird as it might seem, it is not uncommon in Fortran to define constants like one for 1.0d0 and zero for 0.0d0. I thought it was insane at first, but after I got burned by very subtle type errors a few times, I started doing it myself. Have mercy, I only do it in Fortran. I guess the real solution is to never program in Fortran, and to not release old Fortran programmers into the world. ;-) -- Mike Gertz ''Some people started programming a long time ago when FORTRAN was most of what there was. Some of us have adapted and do different things as well now. -- JohnFletcher'' I think you are solving the wrong problem. You should define constants with names describing their purposes not their values. You need to define constants like "NumberOfFingersOnAHand" not "Five". ''Let's not confuse fingers with digits. The human hand normally has five digits, only four of which are fingers, and one digit being the thumb. "NumberOfDigitsOnAHand" should be "five", "NumberOfFingersOnAHand should be "four"'' ''Let's also not forget polydactylism (or hermaphrodism)... The human body isn't really reliable enough to consign to constants. ---- There's a reason for that. Old FORTRAN compilers would use one memory location for each instance of a constant in the source file. That is, if the number 0.0d0 appeared twenty times in a program, it would appear twenty times in the compiled code. Add to that the low memory available to early FORTRAN programs, and you see why a declaration like DOUBLE PRECISION DZERO/0.0d0/ would be useful. And, of course, the older programmers teach the newer programmers. ''Memory storage really was small, bulky and expensive by modern standards thirty years ago. I have a section of memory assembly 4K x 16 bit from a Honeywell 316 which is about the size of 2 Zip disks (holding 500 MBytes)!. Also the 0.0d0 was needed as otherwise the double precision variable was initialized with single precision zero and the rest nonzero rubbish. This could easily cause errors later. -- JohnFletcher'' A similar trick was used often in AtariBasic, in which you would see the first line of a program looking like this: 10 N0=0:N1=1:N2=2:N3=3:N16=16:N100=100:N53248=53248 The reason was that Atari BASIC would store every constant in a program as a float, which took about six bytes, even if the number was a really small integer. On the other hand, variable references used only one or two bytes. So large programs with big memory requirements would save memory with this trick. -- NickBensema This trick was also used in Sinclair Basic on the Sinclair ZX81 (which was known as the Timex 1000 in some parts of the world). Because the machine only had 1Kb of memory as standard, it was common for the first two lines of any program to be: 10 LET O=PI-PI 20 LET I=PI/PI Floating point numbers were stored as five bytes, so this trick saved four bytes each time O or I was used. Also, the symbol PI only took up one byte (Sinclair BASIC was tokenized), so using PI-PI or PI/PI saved two more bytes in the initialization. -- SpencerCollyer ---- It could have been worse. Imagine if it was: #define ONE 0 #define ZERO 1 ''There is a product out there that defines ONE as 0, and TWO as 1 to provide handy constants for a function taking an integer parameter'' I worked once on a program that had a section of code sort of like this (my C is a bit rusty, so forgive any errors...) #if FALSE ... some code. #end When debugging a section of code, I introduced a change that would break the "some code" bit, which I didn't care about because I was going to remove it shortly. Imagine my surprise when the "some code" bit failed to compile. It turned out that, about 2000 lines above this particular code snippet, somebody had done the following: #define FALSE TRUE ---- Didn't see it first hand, but was told about the guy who used a global 'i' in a C program. -- TimVoght I saw that some years ago in a C program. -- Jeff Grigg -- The coder used it in may loops and was trying to save space. (Not that automatic variables on the stack really take up much space!) It was a disaster when you had nested loops... in different functions! '''>-P''' ---- There's a corporate database with a table that has two columns: KEY and VALUE ''Not too bad, at least it can be a perfectly normalized relational table; and the names might make sense, e.g. arbitrary key and current value of securities. It could be a whole database stored as triples in a single table with three columns A, B and C.'' ''We have recently created a table with two columns, KEY and VALUE.. but it certainly seems to make sense for us.. since it stores key/value pairs (shocker there). Since it is used by many other tables, it is not named more specifically.'' ---- I find I'm continually fighting against programmers who don't see a problem with null-semantic names like "value" or "data" and even "variable", but I was somewhat saddened to encounter a body of code written by an ex-colleague where all the variable names were expletives or obscenities. "names don't matter, and it's a bit of a laugh" ... -- FrankCarver ---- Supposedly an old DEC C programming manual recommended writing this: #define PI 3.14156 in case you needed to change the ValueOfPi. ''And if that's the value you were using for pi, you would '''need ''' to change it!'' (''Yeah, yeah. :-) That was as much as I could remember at the time.'') I'll argue in favor of defining PI (but using a more accurate value ;-) public static final double π = 3.14159; -- MartinSpamer [Remainder of very lively discussion of the ValueOfPi moved.] ---- How about const int Minute''''''sPerHour = 60; This is good, not because the value is likely to change, but so as to reduce confusion with Second''''''sPerMinute (which is also 60). -- DaveHarris Be careful here. There are such things as leap minutes, where the number of seconds can be more than 60. http://en.wikipedia.org/wiki/Leap_second Recently encountered this in a production program, used to compare date/time values without the bother of converting to Julian dates: year*980294400 + month*2678400 + day*86400 + hrs*3600 + min*60 + sec It's not an example of BadVariableNames, but it is an example of Bad MagicNumber''''''s: It works, but when I double-checked the numbers, I was surprised to find that they assumed '''366 ''MONTHS'' in a year!''' 2678400 seconds/month = 31 days/month * 24 hours/day * 60 minutes/hour * 60 seconds/minute 980294400 "seconds/year" = 366 months/year * 2678400 seconds/month I can live with 31 days per month -- a reasonable compromise to compute a value used for sorting. But 366 months per year??? That's just an error - they clearly meant to do 366 days per year, but didn't get the numbers right. A set of constants like this would have helped: const Second''''''sPerMinute = 60; const Minute''''''sPerHour = 60; const Second''''''sPerHour = Second''''''sPerMinute * Minute''''''sPerHour; ''...and so on, say with...'' const Ma''''''xDaysPerMonth = 31; ... -- JeffGrigg I think such kind of codes should assume 377 (=31*12) days per year, otherwise it may result that December 31 in year X is greater than January 1 in year (X+1). ''Note: 31*12 is 372, not 377. It should be clear, at least, that the value would have to be even.'' -- DavidConrad ''Well, if it was just for comparison purposes (and with such rough estimates that's all it would be good for)'' ((((year * 100 + month) * 100 + day) * 100 + hrs) * 100 + min) * 100 + sec ''would have been just as effective, at least until any of those values from month onward required more than two digits.'' ---- I had a student once who named his variables after local radio stations. I always expected that I'd see the same program from another student with more meaningful names, but I didn't. ''Yeah, s/he was JustaStudent...'' Someone I went to University with claimed he used the characters in AnimalFarm for variable names - in commercial code. I once had to read code where the variable names were all names in Tolkien or Frank Herbert's Dune. I also had a discussion with a colleague who objected to using ''i'' and ''j'' as indexes in loops etc. He preferred ''US'' for ''universal subscript''. Otherwise he was a wise programmer. We were both working on the same program - in COBOL - and so I went along with US, US2, and so on. A German student in England wrote a large FORTRAN program where every integer variable had a name that started: ''ZEIT'' (meaning "time" in English.) Using obfuscated and / or arbitrary variable names like this is bad for code that is supposed to be useful, but I found it very liberating when learning to code that I could throw the names in without having to bother what each variable is used for. It increases your programmer capability. :) ---- I have a friend that recalls running across a particularly useless name in a basic program once. He chose to name his company after it. Visit him at http://q7.com. -- WardCunningham ---- A program I once worked on had two modes of operation for one algorithm - either it was "Foo''''''Clipping", or it wasn't. So there was a global, called isFooClipping. If you were not Foo''''''Clipping, one array needed to be one element longer. The allocation of said array ended up like this: array = Allocate''''''Memory(baseSize + isFooClipping) Someone has "saved" code and time by reversing the sense of the global. So now we had a isFooClipping variable that's was TRUE (1) if you were '''not''' F''''''ooClipping! -- PaulHudson ''If and only if this is the least arcane solution, I routinely normalize integers in C (or even C++) as Boolean values (0 or 1) and use the Boolean value inside an integer expression. The correct way to do this is with the double-bang notation. For example, !!foo will normalize foo from 0 to 0 or non-zero to 1. Then I could use foo like "length = bar * !!foo;"--although "length = foo ? bar : 0;" is obviously clearer in this case. In the case of isFooClipping, a single bang would have been sufficient to invert and normalize the integral value. -- SunirShah'' ---- How about mixed language names for variables? No, I don't mean Java/C++. Try English/Chinese: const long ZHANYIZHOUQI = 1000; //1000 const long ZHANYIZHOUQI_WITH_NOZZLE_CHANGES = 100; // const int ENDING_SLOT_NUMBER_OF_FRONT_SIDE = 38; const int NOT_SHIELD = 0; const double PANZIGAILUU = 0.1; Anyone care to translate? -- ChrisBrooks I have been writing some PythonLanguage programs for calculating sumo statistics. There just aren't useful English words for banzuke, sanyaku, heya, etc., but a sumo fan reading the code will know exactly what I mean. I think mixed languages are perfectly accessible in context. (For the record, a banzuke is a listing of ranks for wrestlers in a particular tournament, sanyaku translates as "three higher ranks" but means either the four highest ranks or the third and fourth highest ranks, and heya is usually translated as "stable" - it's essentially a wrestling club.) -- JohnFarrell John, this isn't so much a case of using mixed languages, as using the domain language (in this case, sumo jargon) for variables. It's just a coincidence that the domain language consists of words from another natural language. -- RobertWatkins Various languages are often mixed with English in European (Italian, German, Russian, Czech, Finnish...) code: typically there are technical words in English and domain words in local languages, and both categories are very difficult to eradicate completely. Many teams also contain a mix of developers who want to use English, developers who try to use English but make horrible mistakes, developers who don't care and developers who take pride in inventing convoluted or fuzzy neologisms in their national language. -- LorenzoGatti Mixing languages can be a good thing: chances are, Date, Month, etc. are reserved words, but Nap and Honap are not. (That said, woe to any non-Hungarian-speakers who need to work on my company's code...) ''I thought at first that JohnFarrell was leading up to a translation of the terms in the code (differences between Chinese/Japanese notwithstanding). That "zhanyizhouqi" would be some sort of especially skillful sumo throw....'' "ZHANYIZHOUQI" ''might'' have been "campaign period", but I've yet to come across one of those with nozzle changes. ---- ''(Technically a label, not a variable name, but they have the same syntax... ;-)'' VbUnit does this in several places: On Error GoTo Hell ... Hell: ' Error handling code. (I changed all the error handling code labels to have more meaningful names, for the benefit of my customer, where we're trying to get more RegressionTesting going.) ---- That's funny. Recently, a company that I used to work for "officially" banned the usage of "On Error Goto Hell" due to a similar circumstance. To be honest, labels in VB should *only* be used for error handling. Given that, if the only labels that exist are error handlers and if there is only one per method, then "Hell" is perfectly acceptable if used consistently (standardized). Since my production code is 100% c++ now, it's not an issue. I still use it for my VB unit testing code though. It brings me a little joy....bkt ---- And then there's someone who declared "bool Boolean''''''Value;" in several places in a C program, with no consistency of spelling or capitalization, and doesn't see why "tmp" might be a better name... I'm glad I don't have to maintain his code. -- AlastairBridgewater ---- Try this one: int temp = 0; '''AAARRRGGG!!!!''' ''ALL'' variables are ''temp''orary! The information content is '''ZERO (0)''' here!!! ''I have to disagree: although temp/tmp/t *is* overused, inside small blocks it can concisely indicate that the variable is meant as scratch space.'' ---- In a past company, I encountered all three of the following: * A co-worker in the research and development group who named variables after the Marx brothers (Groucho, Chico, Zeppo, and Harpo. I don't think I ever saw Karl though). ''Do you mean Harpo?'' * A software team leader trying to explain to management why he only realized that a team member had been commenting their code in an Eastern European language ''after'' that developer resigned. This supposedly was a MIL-STD-498 project with detailed code reviews... * An autopilot written in FixedPrecisionInteger, in which constants like THREE_DEGREES, FIVE_DEGREES were defined. But, if you did the math, the relationship between FIVE_DEGREES and BITS_PER_DEGREE actually came out to 4.5 degrees or so. The justification was that initial flight tests showed that the ailerons were more effective than originally predicted, and so they had bumped down the values for various control surface settings empirically. Caused me a day's confusion when I first tried to use these "constants" in the navigation module. :-( ''[So the constants would have been...]'' BITS_PER_DEGREE = 72; FIVE_DEGREES = 325; /* (in BITS_PER_DEGREE) */ ''And a little work with a calculator tells you that "FIVE_DEGREES" is really 4.513888... degrees.'' ''[I guessed at the value for FIVE_DEGREES, from the text above. Please correct if I'm off. -- JeffGrigg]'' If only it were so simple. I believe the conversion factor was 57.12-something-something bits per degree, for reasons that predated my time on the project and which now escape me. * In this context, the magic number 57.xxx leaps out; conversion from radians to degrees: 360/(2*3.14159265) = 57.2958... So, the code would have read FIVE_DEGREES .EQU 0101H or something similar. The conversion factors themselves never actually appeared in the code. They were written down in a several-year-old memo in a dusty ThreeRingBinder on the lead engineers' shelf. There was no point putting them in code - the 8088 assembler on the HP64000 development station had no preprocessing capabilities beyond simple (textual) macro substitution. Why weren't the constants commented then? Well, the HP64000 assembler had problems dealing with input files larger than ??? bytes in size, and we were always close to those limits. Development environment limitations were just some of the many areas in which we pushed the limitations of the technology used on that project. ---- No variables, but bad class names. In java, instead of using packages to partition code, the programmer used very long but abbreviated class names all in the same package, and failed to differentiate functionality. SelfSubAdmTermUser, SelfSubAdmRevokeUser, SelfSubAdmAddRole, and a dozen others, all in the SelfSubAdm package. There was also a SelfSub package. I refactored into packages and renamed the classes to remove the leading SelfSubAdm prefix and give them shorter but more meaningful names. In particular to clarify the difference between Term and Revoke (the former was expiring the user, the latter was purging it.) -- StevenNewton ---- From Patrick O'Brian's book "The Unknown Shore": "Guns on the gun-deck," said the quartermaster, with intense relish. "He looked for to find 'em there; hor, hor." "We only ''call'' it the gun-deck," explained Jack. "The guns are all on the upper-deck and quarter-deck, which is natural in a one-decker. The ''Wager'' is a one-decker, Toby." "But there are at least four storeys, or decks, as you say in your jargon," cried Tobias, with some indignation. "Ah," replied Jack at once, "we only ''call'' her a one-decker, you see." ---- I was trying to read through a program my boss wrote that calculated something. It kindof-sortof looked like a tree, except it didn't seem to have any branches. The problem was that the program was actually manipulating a singly linked list, but the node record's "Next" pointer was named "Daughter"! Not only does Daughter imply a hierarchy instead of a list, it would be more typing than using "Left" and "Right". -- AdamVandenberg ''A linked list is a degenerate tree...'' Granted, but in context the name obscured meaning. ---- The sheer laziness of people when naming variables is what disturbs me. "c" for "customer", "u" for user, etc. One of our ex-developers was a C-coder-turned-Java-wiz whose methods were typically 300 lines long and looked like C code. He also used some corrupt form of HungarianNotation (ugh), no doubt helpful since his methods were so ridiculously long. The last straw was when I came across the variable "sz"... zero terminated string in Hungarian, right? Nope: int sz = list.size(); Apparently, typing two more letters would have killed the guy. ''I worked at a job where the GLOBALS!!!! were given one or two letter names in a 20,000 line program. No IDE, just use an editor. Oh yes -- printer variables often contained the vowel removed pnt or ptr. Never mind what pointers were called. Very frustrating.'' ---- I just found this in a beginners tutorial for LingoScriptingLanguage (http://brennan.young.net/Edu/Lingvad.html): For clarity I have called the local variable myV, but you could call it pizza or fireman if you liked. ''I would not, fortunately I do not have permission to do that.'' (follow link) ---- I think most of the myValue or aString variable names come from tutorials and similar how-to books. In the book, the code has no real purpose, so the variable names are irrelevant. -- OleAndersen ''The myV-example is part of a small (but complete) game, intended to show the benefits of using OO.'' Brennan Young (author of the aforementioned lingo tutorial) adds: Out of context it looks as though I am recommending the use of 'pizza' or 'fireman', which is actually the opposite of what I am suggesting. In addition, 'me' in lingo is similar to Java's 'this', so use of the pronouns 'me' and 'my' in Lingo variables (and indeed in Applescript and other related languages) almost exclusively refers to the instance and not the programmer. ''Note use of the phrase 'for clarity'.'' ---- /* important global variables */ unsigned int x; unsigned int xx; unsigned int y; unsigned int yy; The only other comment in the entire system's code was /* Oooh, neat trick */. Once I had to modify third party code with functions named X, Y and Z, each overloaded with completely different parameters and meaning. Apparently it was not a deliberate obfuscation attempt. -- LorenzoGatti ---- The story goes about a customer complaining about a 'obvious' compiler error. The customer handed the code in, so the compilerguys could test it out. all variables where called ''i'', ''ii'', ''iii'' and so on! After days of variable renaming, they found a place where one of the ''i''s was missing. I only hope the customer had to pay for the time spent hunting his bug. ''In theory, it could always be worse. What about variables with the perfectly valid names of _, __, ___, ____, _____, etc.? Of course, this is only made worse by the fact that most fonts don't clearly separate consecutive underscores; oddly enough, BitstreamVera Mono does make underscores distinct, but only in regular and not in bold. -- CodyBoisclair'' ---- On an old VB project, I had asked the other programmer to be sure to use long descriptive variable and control names. This was to make sure he didn't use extremely short variable names (like 'x'), which was the 'standard' in our shop at the time. The form he was working on was quite complicated, but instead of using the names to simplify the form, he ended up using names like lblFraOptFrmAssumptionsTabGrpPrbTabTttL2d and lblOptFraOptFrmAssumptionsTabGrpPrbTabSymMra. ''Couldn't think of a way to abbreviate "Assumptions", eh?'' ---- I have a friend who likes to use variable names that have a string length that is a power of 2. They rarely go beyond 8 letters, though. http://opensource.lineo.com/cgi-bin/cvsweb/pm/MP3/Daemon/bin/pimp?rev=1.1&content-type=text/x-cvsweb-markup ''At 19-04-2005 the link is dead: host not found'' ''disclaimer'': This is not a reflection of the code written at Lineo. My friend has not ever worked for Lineo. If you look at the other code for MP3::Daemon, it's rather sane compared to ''pimp''. -- JohnBeppu ---- Seen recently in a C module: #define AND | ''I have seen this too. The explanation from the programmer was that they got confused by building a bitmask with the | operator, like'' F''''''ileAccessMask = O_READ | O_WRITE | O_BINARY ; ''They thought that it would be less confusing to write:'' F''''''ileAccessMask = O_READ AND O_WRITE AND O_BINARY ; ''I could not convince them that defining OR as AND was potentially a lot more confusing, and they would be better off getting used to the idiom of building bitmasks with |. I have also often seen people use:'' F''''''ileAccessMask = O_READ + O_WRITE + O_BINARY ; ''This works fine as long as each symbol represents a discrete bit, but often leads to errors when combined masks are used:'' NORMAL_ACCESS = O_READ ; F''''''ileAccessMask = NORMAL_ACCESS + O_READ + O_WRITE + O_BINARY ; //wrong! F''''''ileAccessMask = NORMAL_ACCESS | O_READ | O_WRITE | O_BINARY ; //OK! ''Windows has a lot of predefined combined masks, so whereas a UNIX programmer may get away with this idiom, in Windows you will get caught out eventually.'' ---- My buddy's company was in partnership with Microsoft. In fact almost all their funding was coming from MS. They were writing a video game, but having a lot of trouble with the recently released DirectX. They were getting ready for a demo at a big game convention and the last thing they had to do was an installer. The wrote it the night before the convention. (cue ominous music) and then flew out there with the install CD. So the convention starts and my buddy's game is the center piece of the Microsoft booth. Their game is supposed to be running on a giant 16 foot screen over the booth. So they try to install it on the Microsoft booth machines and....it does not work. The company owner is there. The Microsoft VP in charge of the project is there. Crowds are now entering the convention hall. The Microsoft tech guys running the booth are helping trouble shoot. They think maybe it's the drivers, maybe it is the version of the OS. No. No. They open the registry with regedit. Sure enough there was the problem. The variable BILL_GATES_IS_AN_******* was incorrectly defined by the install program. Right on the 16 foot screen in regedit. Microsoft was not amused. ---- When I started working at my present company in April 2000, one of my first tasks was to take over the maintenance of an ancient Java applet that performed financial calculations, updating a pie graph and other goodies in response to user input. The applet consisted in principle of two classes, one of which painted the GUI, the other performed the financial calculations. The painting class had countless instance variables with names like x13, x37, y4, y15. The various components of the applet were positioned according to these variables, the values of which were constantly changing. It took me hours to figure out which variables were connected to which components. Making it worse was the fact that some of the variables weren't ever used! I was glad when we dropped that applet a few months later! -- JohnWebber ''('''ancient''' Java applet? What would you call 15 year old C code I have to maintain???)'' On a related note, I recently had to fix some bugs in some legacy Java code that was notorious for scattered and interconnected sections of code that were never used. It was the definition of SpaghettiCode. There was no way I would have been able to make the fixes without first wasting a lot of time trying to understand the code. I used a my favourite Java IDE (in my case IntellijIdea) which was great at finding unused methods and variables, as well as doing automated refactorings (such as changing bad names and removing unused parameters from method signatures). What a life-saver. It only took a couple of days to clean up the code and then making the fixes was pretty straightforward. ---- I worked on a COBOL program that manipulated a date from mm/dd/yyyy to yy/mm/dd and yyddd and several other formats. The variable names were DATE, DAYT, DAIT, DEIGHT ... ---- For a while I worked at a company using BorlandDelphi. One of the programmers would never rename components created by the VCL. In one form, he had variables for checkbox1, checkbox2, ... checkbox28. At another company I worked for, one of the previous employees had a habit of naming his nouns after places and people. So you'd have variables like texas, newyork, ... Then he'd name the method names stuff like "sucks" so the code would read "texas.sucks()" It was a great. ''I'd almost think ''texas'' might've been a state in a finite state machine...'' * A Perl junky deleted punctuation from the above for no obvious reason; if that was intended as a statement or joke, please be more explicit; the edit by itself came across as merely damage to the text. ---- Working on an insurance system, I found a variable named idiot (ID for the Insurance Object Type). A classic. -- GorkaSiverio Once I was receiving JavaScript Code for webpage. I checked the code and saw that a colleague named the variables like "idiot". The variable holds the login name of the customer. What will you think about a company which names its customers "idiot"? -- AndreasSchweikardt Another story: String str1 = "ACCOUNT"; String str2 = "USER"; String str3 = "AMOUNT"; .... String str18 = "ITEMS"; String value; value = getFromDB(str0); callMethod(value); value = getFromDB(str1); callMethod(value); .... value = getFromDB(str18); callMethod(value); str0 to str18 are used only once. -- AndreasSchweikardt ''That looks a bit like something that certain automated tools for i18n or string externalization would generate.'' No, that guy wasn't that smart like an automated tool. ---- Once had to debug C modules by a certain programmer that contained arrays named ''fuc''. What was the indexing variable? Why ''k'' of course. Real class act that group was. ---- On the other hand, things can go to far.... The system headers for VxworksOs contain (or contained; maybe newer versions of vxWorks have fixed the following bit of BrainDeath) the following macro definitions for boolean values (this is C code): #define TRUE 1 #define FALSE 0 Nothing unusual or nasty about that. However, when our application #included another header, which did the following (which is less acceptable; it was from a locally-developed PinkyAndTheBrain library): typedef int Bool; #ifdef FALSE # undef FALSE #endif #define FALSE ((Bool)0) #ifdef TRUE # undef TRUE #endif #define TRUE ((Bool)(!FALSE)) or something like that. When we built our app, though, all hell broke loose. As it turned out, not because any incompatibility between the two definitions of TRUE and FALSE, which happened to be true (!0 is equal to 1 in our environment, though C doesn't guarantee that in general). The same header files from WindRiverSystems also featured this nonsense, to conditionally include/exclude code. #if FALSE /* excluded code */ #endif With FALSE redefined to be the text "((Bool)0)", this caused the preprocessor to puke. ''(C guarantees that !0 == 1'' from standard section 6.5.3.3: The result of the logical negation operator ! is 0 if the value of its operand compares unequal to 0, 1 if the value of its operand compares equal to 0.'' The lessons learned: * Beware polluting the global namespace, especially in languages like CeeLanguage which don't have hierarchical namespaces as part of the language. A good rule of thumb is that only the application/framework should do so (in C/C++ parlance, that library/module which contains main). * If you must redefine TRUE and FALSE, go ahead. However, don't do #if TRUE and #if FALSE. #if 1 and #if 0 suffice, are just as clear, are common CeeIdioms, and aren't subject to having 0 and 1 redefined. (Well, you could do #define 0 and #define 1, but we won't go there...) * Unless you are writing CeeCeePlusPlus system header files (a thankless chore) or need to interface to poorly-written C/C++ header files, avoid #undef. It all by itself is a CodeSmell. * I had use #undef because the system C header file left me #define Copy''''''Memory memcpy when I wasn't actually linking against the C runtime library, just the system call library. --JoshuaHudson -- ScottJohnson ---- PerlLanguage has plenty of scope for BadVariableNames. You could have these sets of variables, although it's hard to know why you'd want to: $chomp, @chomp, %chomp $print, @print, %print $foreach @foreach %foreach Which means you could conceivably write the following valid Perl: print push @chomp,chomp $print{$foreach} foreach $foreach (keys %print); But please don't! (As seen originally in comp.lang.perl.misc at http://groups.google.com/groups?selm=tqlfcc.trn.ln%40goaway.wombat.san-francisco.ca.us .) Actually, I understood all that on the first pass, thanks to perl's sigils. While some people love to hate PerlLanguage PerlLanguage for its "ugly" syntax, there's a lot of clever stuff going on with it. Then again I've been programming in perl for some 8 years, and it has undoubtedly fried my brain. ---- There are these rather infamous examples in FortranLanguage, which traditionally has no reserved words: INTEGER REAL REAL INTEGER IF (IF .EQ. THEN) THEN THEN = ELSE ELSE ELSE = IF ENDIF And you thought the Perl statement above was a headache to parse! A similar example in PliLanguage was mentioned in the Organization of Programming Languages class I'm in: IF IF = THEN THEN THEN = ELSE; ELSE ELSE = END; END; -- CodyBoisclair ---- Yeah - I hate sesquipedalia verba, so I have presented a little ditty in a much more programmer friendly form - sesquipedalium phrasum - Cinematic Emporium - programmerese - i sesquipedalium phrasum - super sensorium - programmerese - j sesquipedalium phrasum - mutual masturbatorium - programmerese - k The new i Is not just a j But a highly effectual, Heterosexual k There. That's much clearer ---- What about bad class names? public class AccountPermissionsRulesDipswitch { Dipswitch? A dipswitch is a thing for manually selecting clock speeds, bus timings etc. on a motherboard, or manually selecting the network address on ancient Arcnet network cards. Are you telling me that an administrator has to configure account permissions by manually changing dipswitches on the server? I'm going home... ''Sounds like a dipshit.'' ---- From the same coder that brought you the above: private final static String DPHFROMACC = "DPHFROMACC"; Why? ''To avoid typo's?'' It's used a massive total of once. Maybe he just wanted to be sure. :-) ---- A coder on my old project just couldn't stop his fingers from doing the Hungarian thing. At the same time, we were commonly packing C++ structs into BSTRs, to use over DCOM. (Ah, the very bad old days...) So, seeing that a BSTR argument was really a string, he named it "bstrstr". With the type of the variable embedded twice into the name, there is certainly no room for the variable's purpose! -- JimHughes ---- I was in a C class with a guy who named his variables 1var, 2var, 3var, and so on. When it wouldn't compile, the instructor reminded him that variables had to start with a letter or an underscore. He changed them to _1var, _2var, _3var, etc. -- DanielKoning ---- I currently maintain and develop extensions to legacy shell and perl scripts. Part of the current infrastructure is a "template" program used to generate SQL which has the following lovely features: * All template variables are named with two digit numbers * Information is passed to the template (partially parsed as a perl script) by the ''numbered argument variables passed o to the template interpreter perl script'' * The templating process is represented in myriad shell scripts with the following korn shell method # Run a file through ProcessTemplateNew.pl # Requires at least 2 arguments: template_file query_file [[arg3] [arg4] [arg5] [arg6] [arg7] [arg8] [arg9]] do_template() { ${PerlDir}/ProcessTemplateNew.pl "${3}" "${4}" "${5}" "${6}" "${7}" "${8}" "${9}" < ${1} > ${2} MyResult=$? if [[ ${MyResult} -ne 0 ]] then exit_msg "Cannot generate template ${1}" fi } * Most template files have logical processing that occurs ''within'' them, looking like such: ##00=$ARGV[0] ##99=$ARGV[1] ##01=dc_addmonth($ARGV[2],0) ##02=dc_fmtmdy(dc_firstday($ARGV[2])) ##03=dc_fmtmdy(dc_lastday($ARGV[2])) ##04=dc_fmtmdy(dc_addcrdays(dc_lastday($ARGV[2]))) ##05=dc_fmtmdy(dc_firstday(dc_addmonth($ARGV[2],-1))) ##06=dc_fmtmdy(dc_lastday(dc_addmonth($ARGV[2],-1))) ##07=dc_fmtmdy(dc_addcrdays(dc_lastday(dc_addmonth($ARGV[2],-1)))) ##08=dc_fmtmdy(dc_firstday(dc_addmonth($ARGV[2],-24))) ##08=dc_fmtmdy(dc_firstday(dc_addmonth($ARGV[2],-23))) ##09=dc_fmtmdy(dc_lastday(dc_addmonth($ARGV[2],-7))) ##09=dc_fmtmdy(dc_firstday(dc_addmonth($ARGV[2],-5))) ##10=dc_fmtmdy(dc_firstday(dc_addmonth($ARGV[2],-6))) ##11=dc_addmonth($ARGV[2],-1) ##12=dc_addmonth($ARGV[2],-60) ##13=dc_addmonth($ARGV[2],-59) ##80=$ARGV[3] eq '' ? '' : '--' * And lastly, you might have noticed by variable "##80", ''the templating engine is frequently used to generate variables used to programatically comment out '''entire chunks of SQL''' '' ---- Back when I wrote code for the Mac for a living, the Mac system headers actually defined global variables named h & v. Never tracked them down to see exactly where they came from, but I was always horrified whenever I discovered shipping code of mine that used h & v & forgot to declare them locally. When I'm in the zone, & I just can't think of an appropriately descriptive name, I'd rather use "bob" or "foo" or "dracula" & get things done than agonize until I come up with a GoodVariableName. I usually try to fix them later, but sometimes I don't. -- RobertFisher I'm prone to variable names like 'ick' or 'myPairPartnerIsntPayingAttention' ...until they catch me!!! >;-> ''You're caught. See me in my office, first thing Monday morning.'' -- Y''''''ourBoss ---- A long time ago, I was working with credit cards. And there was a table in the database for the shops. Shop, in Spanish, can be translated as "establecimiento" in this context. Because of it, the table was named by me as "establishment". I still laugh at it. -- AurelianoCalvo ---- In a 200-level CS class in the late 90s, I had to review a fellow student's code (he was a teenager, I was nearly 40 and a night student). At the top of his program he declared several variables thusly: char mander; char meleon; char izard; If you are going to be a CS student, you have to love your Pokémon! ---- A project I was on at Apple used internally-popular naming conventions, with constants prefaced with 'k'. In our sources we had #define k32 28 which turned out to be a hardware register bit configuration for putting an adapter into some kind of 32-bit mode, but you sure wouldn't have known it without some research. ---- We have a database table that refers to server cache statistics, with the aptly named columns ISMISS and ISHIT (we rarely read the second one as "is hit"). -- jason. ---- static const int INIT = 0; static const int DELETE = 1; static const int KEEP = 1; That's going to keep a few people up at night. ---- I found this in code for displaying a TV schedule as a grid. unsigned int time_4ths = seconds / (60*15); Hint: makes perfect sense in Portuguese... ---- On my previous job I had to maintain a massive database. Amazingly one of the tables was named ASS (an acronym for Account Security Settings or smth. similar). We had lots of fun when looking at INSERT INTO ASS statements ... ---- See: GoodVariableNames, MeaningfulName, CodingConventions, HowToWriteUnmaintainableCode, PetPeeve, MetasyntacticVariable and FunnyThingsSeenInSourceCodeAndDocumentation, UnderscoreVersusCapitalAndLowerCaseVariableNaming, DontNameClassesObjectManagerHandlerOrData FocusOnConcepts ---- CategoryCodingIssues CategoryNaming