Preprocessor macro to remove code if compiled after a certain date - gcc

I would like three lines of code not to be included if compiled after a certain date.
The reason being is they provide backwards compatibility. To support a staggered release between client and embedding it is required to be there now.
Once the next software release comes along this support is to be dropped to force customers to upgrade the embedded software. Since this is a few months away there is risk of these lines being forgotten.
So ideally I would like a
#if __DATE__ > MyDate
code here
#endif
or something equivalent.
Is there any way of doing this?
*The code is compiled with GCC

This solution is specifically for Windows platform and is something I use in production.
I exploit the environment variable %DATE%, and in a batch file used to launch my IDE, I have VA_CURRENT_DATE=%DATE:~6,4%%DATE:~3,2%%DATE:~0,2% (which transforms to an ISO8601 date for my specific locale).
Then in my preprocessor definitions for my project I define VA_BUILD_DATE to VA_CURRENT_DATE
Then I have some code like:
long day = VA_BUILD_DATE;
long year = day / 10000;
day -= year * 10000;
long month = day / 100;
day -= month * 100;

You can't do this with __DATE__, because it expands to a string constant, and string constants can't be used in #if. Also, setting a fixed date is a bad idea, because you may need to do bug-fix releases to the older version that should preserve the backward compatibility.
(Do you really need to drop backward compatibility? If it's only three lines of code, consider just keeping them around forever. Your customers will not thank you for "forcing them to upgrade.")
The good way to do this sort of thing is via your version control system. You should be maintaining a branch for each release anyway, so write your code like this:
#ifdef BACKWARD_COMPAT_VERSION_1_0
compatibility code here
#endif
and then change the Makefile on the release branch, only, to include -DBACKWARD_COMPAT_VERSION_1_0 in your CFLAGS.

Now I am running the risk of not answering your question directly. But I'd take the risk and suggest you NOT to do so. How many times does a project get released on time? The date is, too prone to change. And you never know that.
Why not use the version of your project instead?
// Only defined in old projects that you want this legacy code in.
#ifdef OLD__VERSION
code here
#endif

Unfortunately this won't work as __DATE__ produces a string in the form "Sep 5 2013", which is useless for comparison.
Ideally the compiler should support a constant like __DATEFLAT__ which produces an integer like 20130905, which would be ideal for such as task. However this doesn't exist.

Related

Revision histories and documenting changes

I work on legacy systems and I used to see revision history of files or functions being modified every release in the source code, for example:
//
// Rev. No Date Author Description
// -------------------------------------------------------
// 1.0 2009/12/01 johnc <Some description>
// 1.1 2009/12/24 daveb <Some description>
// -------------------------------------------------------
void Logger::initialize()
{
// a = b; // Old code, just commented and not deleted
a = b + c; // New code
}
I'm just wondering if this way of documenting history is still being practiced by many today? If yes, how do you apply modifications on the source code - do you comment it or delete it completely?
If not, what's the best way to document these revisions? If you use version control systems, does it follow that your source files contain pure source codes, except for comments when necessary (no revision history for each function, etc.)?
Just rely on your version control system. Yes, just pure source code. If code is commented out I delete it. If I'm not sure I leave it there with a TODO comment.
I don't insert comments to reference tickets in the source but in the commit message. You don't need to document in the code what it used to look like.
Manual revision histories are hard to maintain, hence almost always out-of-date.
I trust the revision control system to give me this information. In addition to be correct, it can be much more precise, for example with pre-line annotations (who has changed that line last).
I do insert comments to reference tickets in the bug tracking system directly in the source when I feel that it is necessary, even though this info is also available in the commit message.
It does make sense to have a changes/release notes file per project (not per source file) that is manually maintained and updated for every release.
I used to work for a company that mandated this type of comment on all SPs that went to the database. I found it incredibly tedious and completely redundant over the notes we were required to enter into our source control system.
The main use of the inline comments was to validate that the deployment to a new environment was successful (like production). This also was a tedious process and was only used because there was no other method.
I have never found a use for inline comments like this anywhere else and found they only caused tedious headache inducing work.
I would advocate for a system where source control manages the comments and revision history and not the code. That is one of the purposes of the system and that's the best place for it. IMO.
Nowadays the best way to document these revisions is to let your version control do it, but that also means that you have to enforce the rule that developers write meaningful commit comments, or at least some bug tracking numbers, so it would be easy to figure out what they committed what for.
I've never seen revision history in code comments. At most I've seen the Javadoc #version tags to document the version.
The oldest version control method is like this:
logo2007-1.png, logo2007-2.png
Version control should be the best solution.
see also: http://betterexplained.com/articles/a-visual-guide-to-version-control/

Stop Visual Basic 6 from changing my casing

Very simple question that is apparently impossible to find a decent answer to: How can I make Visual Basic 6 stop changing my ^##*ing variable casing!?!
I know that the general opinion of a great many VB users is that this "feature" is actually quite helpful, but I doubt that they use it much with any source control system. This is absolutely INFURIATING when you are trying to collaborate on a project of any significant size with several other developers. If ignored, you produce thousands of false-positive "changes" to your files (even ones with no actual code changes!) that pollute the revision history and make it near impossible in some cases to locate the actual change that took place.
If you don't ignore it (like my office, where we have been forced to implement a "no unneeded case change" policy), you spend 5x the time you would normally on each commit because you have to carefully revert out VB's "corrections" on every file, sometimes reverting hundreds of lines to put in a one line change.
Surely there must be a setting, plugin, hack, etc. out there that can remove this unwanted "feature"? I am willing to take any method I can get as long as it doesn't require me to pick through piles of phantom diffs. And to squash a couple of complaints up front: No, I can't turn off case detection in my diff tool, that's not the point. No, we can't just make the case changes globally. We're working with hundreds of thousands of LOC being worked on by multiple developers spanning many years of development. Synchronizing that is not feasible from a business standpoint. And, finally: No, we cannot upgrade to VB.net or port to another language (as much as I would love to).
(And yes, I am just a tiny bit peeved at the moment. Can you tell? My apologies, but this is costing me time and my company money, and I don't find that acceptable.)
Depending on your situation adding
#If False Then
Dim CorrectCase
#End If
might help.
Here is a real world scenario and how we solved it for our 350k LOC VB6 project.
We are using Janus Grid and at some point all the code lines which referenced DefaultValue property of JSColumn turned to defaultValue. This was an opportunity to debug the whole IDE nuisance.
What I found was that a reference to MSXML has just been added and now the IDE picks up ISchemaAttributes' defaultValue property before the Janus Grid typelib.
After some experiments I found out that the IDE collects "registered" identifiers in the following order:
Referenced Libraries/Projects from Project->References in the order they are listed
Controls from Project->Components (in unknown order)
Source Code
So the simple fix we did was to create a dummy class/interface with methods that hold our proper casing. Since we already had a project-wide typelib we referenced from every project before anything other typelib, this was painless to do.
Here is part of the IDL for our IUcsVbIntellisenseFix interface:
[
odl,
uuid(<<guid_here>>),
version(1.0),
dual,
nonextensible,
oleautomation
]
interface IUcsVbIntellisenseFix : IDispatch {
[id(1)] HRESULT DefaultValue();
[id(2)] HRESULT Selector();
[id(3)] HRESULT Standalone();
...
}
We added a lot of methods to IUcsVbIntellisenseFix, some of them named after enum items we used to misspell and whatever we wanted to fix. The same can be done with a simple VB class in a common library (ActiveX DLL) that's referenced from every project.
This way our source code at some point converged to proper casing because upon check-out the IDE actually fixed the casing as per IUcsVbIntellisenseFix casing. Now we can't misspell enums, methods or properties even if we try to.
SIMPLE WAY: Dim each variable in the case that you want. Otherwise, VBA will change it in a way that is not understandable.
Dim x, X1, X2, y, Yy as variant
in a subroutine will change ALL cases to those in the Dim statement
I can sympathise. Luckily we're allowed to turn off case sensitivity in our version control diff tool!
It seems the VB6 IDE automatic case-correction occasionally changes case in variable declarations and references, perhaps depending on the order in which modules are listed in the VBP file? But the IDE doesn't tell you that the file needs to be saved. So the problem only shows up when you saved the file because of another edit. We briefly tried to prevent this by checking out all the files in a project and setting the case carefully, but it didn't go away.
I suppose you could list the variable names that are affected - the usual suspects are one letter names like "I", "X" and "Y", perhaps because they are used in standard event handlers like MouseDown. Then write an add-in that'll search for all declarations " As" and force the case to upper. Run the add-in on your modules before you check them in. You might be able to trigger the add-in to run automatically when you save in VB6.
EDIT: Something I've just thought of: adapt Fred's answer. From now on, every time you check in a file, add a block at the top to establish canonical case for the usual suspects. If nothing else, it's easier than reverting hundreds of lines by hand. Eventually you will have this block in every file & maybe then the problem will stop happening.
#If False Then
Dim I, X, Y ' etc '
#End If
I standardised the case across the codebase, normally by using the examples above (Dim CorrectCase), and removing it again.
I then triggered VB to save EVERY file, by doing a case sensitive search/replace of "End" with "End" (no functional change, but enough to get VB to resave).
Once that was done, I could then do a single commit to standardise the case, making it MUCH easier to keep on top of it at a later date.
In this example VB6 was changing the case of the following line following a typo I made when referencing a library: -
Dim MyRecordset As ADODB.REcordset
Ugly, and now every other instance of an ADODB.REcordset thus acquired the new misspelling. I fixed this as follows: -
Type in a new declaration as follows
Dim VB6CasingSucks AS ADODB, Recordset
Note the comma and space after ADODB. Hit [ENTER] for VB6 to check the line.
At this point all instances of REcordset change back to Recordset.
Delete your new declaration.
I don't know if this fix will help with enums/other variable names.
Specifically for controlling the case of enum values, there is a VB6 IDE add-in which may be helpful. Enums seem to have a slightly unique version of this problem.
As described in the link below:
The VB6 IDE has an annoying quirk when it comes to the case of Enum
members. Unlike with other identifiers, the IDE doesn't enforce the
case of an Enum member as it was declared in the Enum block. That
occasionally causes an Enum member that was manually written to lose
its original case, unless a coder typed it carefully enough.
...
However, if a project contains a lot of Enums and/or a particular Enum
has a lot of members, redeclaring the members in each of them can get
quite tedious fast. ...
Ref: http://www.vbforums.com/showthread.php?778109-VB6-modLockEnumCase-bas-Enforce-Case-of-Enums
...load and unload the add-in as needed via the Add-In Manager
dialog box. Usage is as simple as selecting the entire Enum block,
right-clicking and then choosing the "Lock Enum Case" context menu
item.
I have a similar problem:
in a bas module there I wrote :
Private sub bla_bla()
Dim K as integer
End Sub
so in a class module the Dim k as integer will automatically be replaced by IDE become 'Dim K as integer' <-- it's not logical but then:
I correct the bas module become:
Private sub bla_bla()
Dim k as integer
End Sub
then magically the problem in the class module was solved (still be k and not automatically replaced by IDE become K). Sorry I'm poor in English
I don't think there's any to do it. The IDE will change the case of the variable name to whatever it is when it's declared. But, honestly, back in the day I worked on several large VB6 projects and never found this to be a problem. Why are people on your development team constantly changing variable declarations? It seems like you have not established a clear variable naming policy that you enforce. I know your upset, so no offense, but it might be your policies that are lacking in this regard.
Unfortunately, according to this SO thread, alternate VB6 IDEs are hard to come by. So, your best bet is to solve this problem via policy. Or move to VB.NET. :)
Wow. I've spent a lot of time programming in VB6 and I have no idea what you're on about. The only thing I can think you're referring to is that intellisense will change the capitalization of variable names to match their declarations. If you're complaining about that, I would have to wonder why the hell they've been entered any other way to begin with. And if that is your problem, no, there's no way to disable it that I'm aware of. I'd suggest you, in one go, check out every file, make sure the caps on the declarations and uses of variables all match and check back in.

Configuration Management - History in Code Comments

Let me pose a bit of background information before asking my question:
I recently joined a new software development group that uses Rational tools for configuration management, including a source control and change management system.
In addition to these tools, the team has a standard practice of noting any code changes as a comment in the code, such as:
///<history>
[mt] 3/15/2009 Made abc changes to fix xyz
///</history>
Their official purpose for the commenting standard is that "the comments provide traceability from requirement to code modification".
I am preparing to pose an argument that this practice is unnecessary and redundant; that the team should get rid of this standard immediately.
To wit - the change management system is the place to build traceability from requirement to code modification, and source control can provide detailed history of changes by performing a Diff between versions. When source code is checked in, the corresponding change management ticket is noted. When a CM ticket is resolved, we note which source code files were modified. I believe this provides a sufficient cross-reference for the desired traceability.
I would like to know if anyone disagrees with my argument. Am I missing some benefit of commented source code history that change management and source control systems cannot provide?
For myself, I have always found such comments to be more trouble than they're worth: they can cause merge conflicts, can appear as 'false positives' when you're trying to isolate the diffs between two versions, and may reference code changes that have since been obsoleted by later changes.
It's often (not always, but often) possible to change version-control systems without losing metadata. If you were to move your code to a system that doesn't support this, it would not be hard to write a script to convert the change history into comments before the cutover.
A comment allows you to find all the changes and their reasons in the code right where they are relevant without having to dig into diffs and version control system intricacies. Furthermore, should you decide to change of version control system, the comments will stay.
I worked on a large project with similar practice that had changed of source control system twice. There wasn't a day when I wasn't glad to have these comments.
Is it redundant? Yes.
Is it unnecessary? No.
I've always thought that code should be, of course, under version control, and that the current source code (the one that you can open and read today) should be valid only in present tense.
It doesn't matter if a report could have up to 3 axis in the past and last month you updated it to support up to 6 axis. It doesn't matter if you expanded some function or fixed some bug, as long as the current version can be easily understood. When you fix a bug, just leave the fixed code.
There's an exception, though. If (and only if) the fixed code looks less intuitive to you than the previous, incorrect one; if you feel that someone might come tomorrow and, just by reading the code, be tempted to change it back to what "seems more correct", then it's good to add a comment: "This is done this way to avoid... blah blah blah." Also, if the problem behind is an infamous war story inside the team's culture, or if for some reason the bug report database contains very interesting information about this part of the code, I wouldn't find it incorrect to add "(see Bug Id 10005)" to the explaining comment.
The one that jumps to mind to me is vendor lockin. If you ever moved away from Rational, you'd need to make sure that the full change history was maintained during the migration - not just the version of the artifacts.
When you're in the code you need to know why it's structured like that, hence in code commenting. Tools that sit outside the code, good though they may be, require far too much of a context shift in your brain to be useful. As well as that, trying to reverse engineer the code intent from documentation and a diff is pretty damn hard, I'd much rather read a line of comment any day.
There was a phase in the code I work on, back in the 1994-96 time frame, where there was a tendency to insert change history comments at the top of the file. Those comments are now meaningless and useless, and one of the many standard cleanups I perform when editing files containing such comments is to remove them.
In contrast, there are also some comments with a bug number at the location where the change is made, typically explaining why the ridiculous code is as it is. These can be very helpful. The bug number gives you somewhere else to look for information, and fingers the culprit (or victim - it varies).
On the other hand, items like this one - genuine; cleaned up last week - make me grit my teeth.
if (ctab->tarray && ctab->tarray[i])
#ifndef NT
prt_theargs(*(ctab->tarray[i]));
#else
/* Correct the parameter type mismatch in the line above */
prt_theargs(ctab->tarray[i]);
#endif /* NT */
The NT team got the call correct; why they thought it was a platform-specific fix is beyond me. Of course, if the code had used prototypes instead of just parameterless declarations before now, then the Unix team would have had to fix the code too. The comment was a help - assuring me that the bug was genuine - but exasperating.

Enforcing a coding style [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
Years ago when I was starting a small development project, the other developers and I sat down and agreed on a compromise brace and indentation style. It wasn't anybody's favourite, but it was something that nobody really hated. I wrote a .indentrc configuration file to that style, and had a check-in trigger that would run indent on every file as it was being checked in. That made it so that it didn't matter what style you wrote your code in, it would end up being the group standard before anybody else saw it. This had the advantage of consistency. But I've never seen anybody else do it this way before or since.
So what say the rest of you? Great idea, or abomination?
I'd say good idea. I'd take it a step further and make everyone use the config file in their IDE so that they were writing in the agreed upon style by default. If they're going to have to look at everyone else's code in the neutral style, they might as well get used to it. Even their own code should be in the neutral style after one check-in check-out cycle, so why develop new code in their own personal style?
Adopting a neutral coding style is definitely a good idea. However, only enforcing the coding style when the source is checked in may or may not be a good idea (see also Bill's and Elie's answers below).
Using the check-in hook:
Pro: Allows coders to write however they wish, so they don't have to think about the standard or change the way they write code. This minimizes resistance to the policy, and won't negatively impact their productivity when writing code.
Con: Your coders may have only a passing familiarity with the neutral style, so you aren't getting the full benefit of everyone using "the same" style. If your programmers ever have to work together in a pair programming setup, they are still going to be subjected to one another's programming style on the screen, which is going to be different from their own style or the neutral style.
Going one step further, using the neutral style during development:
Pro: Encourages fluency in the neutral style, everyone can always read everyone else's code before and after it's checked in.
Con: You'll encounter more resistance from your developers doing it this way. Depending on your culture, it could be more trouble than it is worth.
If you limited it to enforcing style on braces and indentation, then I think it's a good idea. However, if you were to try to enforce every single formatting standard, then it probably wouldn't be. In my opinion, there are times when it makes sense to break the standard. For example, I prefer
int x = y * z;
to
int x = y*z;
because it's easier to read. However, I vastly prefer
int a = b*c + d*e;
to
int a = b * c + d * e;
because the spacing represents the order of operations.
So your policy of enforcing indentation and braces sounds really good. But if someone ever tried to blindly enforce other spacing rules, I don't think it would work well.
That sounds like a good idea. As long as the style you end up with is not something completely strange, that's a good way to make sure your developers use the style. And it has the added benefit that they don't have to code that way - it will get reformatted for them when they check in their changes. It would be nice to have a tool like that available that you can plug into your CVS (generic term).
We use TFS with a check in policy that runs a set of Stylecop rules. If your code doesn't pass, you can't check it in. Works very well indeed. Aside from a consistant style and good commenting throughout, it also seems to have increased the general quality of the code - perhaps because the developer is forced to describe what every method, event, etc does they are forced to think about the code more before check in.
Only an MS solution, but worthwhile if it's available to you.
The biggest problem with using automatic code formatters is when the code formatter can't handle every scenario.
For example, if you have lots of SQL in your code, you probably format the SQL automatically. But if your SQL is longer than one line (how long is a line, anyway?) then
you have to format it. So far I've yet to see a good formatter than can deal with this properly.
Example:
String sql = "SELECT * FROM USERS WHERE ID = ? AND NAME = ? AND IS_DELETED = 'N'";
vs
String sql =
"SELECT * " +
"FROM USERS " +
"WHERE ID = ? " +
" AND NAME = ? " +
" AND IS_DELETED = 'N'";
The second format is more readable when you have really long queries. Most formatters would de-format that into one long line up to the line length.
However if all you're doing is turning
if(x=1) print("blah"); else print("eep!");
into
if (x = 1) {
print("blah");
} else {
print("eep!");
}
then the formatter is ok. We do something similar at work; it isn't enforced by the CVS tool but rather by the IDE. Works reasonably well.
There is a project called EditorConfig can somewhat solve the issue. However, it currently only solves indentation issues.
EditorConfig contains plugins for many different editors, and a file format standard. By creating an .editorconfig file in the root of your project, and installing the corresponding plugin, the editor will format your code when you type them.
This is a general way (unlike indentrc, not limited to C/C++), but you can still take a look at this solution.
I believe you have decided on your development environment by now. If you use Eclipse you can enable the Format Source save action on the Java editor, which reformats at every save. The major benefit from this is that source chances are marked in your source repository at the time when they were done, not when the source was reformatted later.
Make it an automatic step. You will appreciate it later.

What was the strangest coding standard rule that you were forced to follow? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
When I asked this question I got almost always a definite yes you should have coding standards.
What was the strangest coding standard rule that you were ever forced to follow?
And by strangest I mean funniest, or worst, or just plain odd.
In each answer, please mention which language, what your team size was, and which ill effects it caused you and your team.
I hate it when the use of multiple returns is banned.
reverse indentation. For example:
for(int i = 0; i < 10; i++)
{
myFunc();
}
and:
if(something)
{
// do A
}
else
{
// do B
}
Maybe not the most outlandish one you'll get, but I really really hate when I have to preface database table names with 'tbl'
Almost any kind of hungarian notation.
The problem with hungarian notation is that it is very often misunderstood. The original idea was to prefix the variable so that the meaning was clear. For example:
int appCount = 0; // Number of apples.
int pearCount = 0; // Number of pears.
But most people use it to determine the type.
int iAppleCount = 0; // Number of apples.
int iPearCount = 0; // Number of pears.
This is confusing, because although both numbers are integers, everybody knows, you can't compare apples with pears.
No ternary operator allowed where I currently work:
int value = (a < b) ? a : b;
... because not everyone "gets it". If you told me, "Don't use it because we've had to rewrite them when the structures get too complicated" (nested ternary operators, anyone?), then I'd understand. But when you tell me that some developers don't understand them... um... Sure.
To NEVER remove any code when making changes. We were told to comment all changes. Bear in mind we use source control. This policy didn't last long because developers were in an uproar about it and how it would make the code unreadable.
I once worked under the tyranny of the Mighty VB King.
The VB King was the pure master of MS Excel and VBA, as well as databases (Hence his surname : He played with Excel while the developers worked with compilers, and challenging him on databases could have detrimental effects on your career...).
Of course, his immense skills gave him an unique vision of development problems and project management solutions: While not exactly coding standards in the strictest sense, the VB King regularly had new ideas about "coding standards" and "best practices" he tried (and oftentimes succeeded) to impose on us. For example:
All C/C++ arrays shall start at index 1, instead of 0. Indeed, the use of 0 as first index of an array is obsolete, and has been superseded by Visual Basic 6's insightful array index management.
All functions shall return an error code: There are no exceptions in VB6, so why would we need them at all? (i.e. in C++)
Since "All functions shall return an error code" is not practical for functions returning meaningful types, all functions shall have an error code as first [in/out] parameter.
All our code will check the error codes (this led to the worst case of VBScript if-indentation I ever saw in my career... Of course, as the "else" clauses were never handled, no error was actually found until too late).
Since we're working with C++/COM, starting this very day, we will code all our DOM utility functions in Visual Basic.
ASP 115 errors are evil. For this reason, we will use On Error Resume Next in our VBScript/ASP code to avoid them.
XSL-T is an object oriented language. Use inheritance to resolve your problems (dumb surprise almost broke my jaw open this one day).
Exceptions are not used, and thus should be removed. For this reason, we will uncheck the checkbox asking for destructor call in case of exception unwinding (it took days for an expert to find the cause of all those memory leaks, and he almost went berserk when he found out they had willingly ignored (and hidden) his technical note about checking the option again, sent handfuls of weeks before).
catch all exceptions in the COM interface of our COM modules, and dispose them silently (this way, instead of crashing, a module would only appear to be faster... Shiny!... As we used the über error handling described above, it even took us some time to understand what was really happening... You can't have both speed and correct results, can you?).
Starting today, our code base will split into four branches. We will manage their synchronization and integrate all bug corrections/evolutions by hand.
All but the C/C++ arrays, VB DOM utility functions and XSL-T as OOP language were implemented despite our protests. Of course, over the time, some were discovered, ahem, broken, and abandoned altogether.
Of course, the VB King credibility never suffered for that: Among the higher management, he remained a "top gun" technical expert...
This produced some amusing side effects, as you can see by following the link What is the best comment in source code you have ever encountered?
Back in the 80's/90's, I worked for an aircraft simulator company that used FORTRAN. Our FORTRAN compiler had a limit of 8 characters for variable names. The company's coding standards reserved the first three of them for Hungarian-notation style info. So we had to try and create meaningful variable names with just 5 characters!
I worked at a place that had a merger between 2 companies. The 'dominant' one had a major server written in K&R C (i.e. pre-ANSI). They forced the Java teams (from both offices -- probably 20 devs total) to use this format, which gleefully ignored the 2 pillars of the "brace debate" and goes straight to crazy:
if ( x == y )
{
System.out.println("this is painful");
x = 0;
y++;
}
Forbidden:
while (true) {
Allowed:
for (;;) {
a friend of mine - we'll call him CodeMonkey - got his first job out of college [many years ago] doing in-house development in COBOL. His first program was rejected as 'not complying with our standards' because it used... [shudder!] nested IF statements
the coding standards banned the use of nested IF statements
now, CodeMonkey was not shy and was certain of his abilities, so he persisted in asking everyone up the chain and down the aisle why this rule existed. Most claimed they did not know, some made up stuff about 'readability', and finally one person remembered the original reason: the first version of the COBOL compiler they used had a bug and didn't handle nested IF statements correctly.
This compiler bug, of course, had been fixed for at least a decade, but no one had challenged the standards. [baaa!]
CodeMonkey was successful in getting the standards changed - eventually!
Once worked on a project where underscores were banned. And I mean totally banned. So in a c# winforms app, whenever we added a new event handler (e.g. for a button) we'd have to rename the default method name from buttonName_Click() to something else, just to satisfy the ego of the guy that wrote the coding standards. To this day I don't know what he had against the humble underscore
Totally useless database naming conventions.
Every table name has to start with a number. The numbers show which kind of data is in the table.
0: data that is used everywhere
1: data that is used by a certain module only
2: lookup table
3: calendar, chat and mail
4: logging
This makes it hard to find a table if you only know the first letter of its name.
Also - as this is a mssql database - we have to surround tablenames with square brackets everywhere.
-- doesn't work
select * from 0examples;
-- does work
select * from [0examples];
We were doing a C++ project and the team lead was a Pascal guy.
So we had a coding standard include file to redefine all that pesky C and C++ syntax:
#define BEGIN {
#define END }
but wait there's more!
#define ENDIF }
#define CASE switch
etc. It's hard to remember after all this time.
This took what would have been perfectly readable C++ code and made it illegible to anyone except the team lead.
We also had to use reverse Hungarian notation, i.e.
MyClass *class_pt // pt = pointer to type
UINT32 maxHops_u // u = uint32
although oddly I grew to like this.
At a former job:
"Normal" tables begin with T_
"System" tables (usually lookups) begin with TS_ (except when they don't because somebody didn't feel like it that day)
Cross-reference tables begin with TSX_
All field names begin with F_
Yes, that's right. All of the fields, in every single table. So that we can tell it's a field.
A buddy of mine encountered this rule while working at a government job. The use of ++ (pre or post) was completely banned. The reason: Different compilers might interpret it differently.
Half of the team favored four-space indentation; the other half favored two-space indentation.
As you can guess, the coding standard mandated three, so as to "offend all equally" (a direct quote).
Not being able to use Reflection as the manager claimed it involved too much 'magic'.
The very strangest one I had, and one which took me quite some time to overthrow, was when the owner of our company demanded that our new product be IE only. If it could work on FireFox, that was OK, but it had to be IE only.
This might not sound too strange, except for one little flaw. All of the software was for a bespoke server software package, running on Linux, and all client boxes that our customer was buying were Linux. Short of trying to figure out how to get Wine (in those days, very unreliable) up and running on all of these boxes and seeing if we could get IE running and training their admins how to debug Wine problems, it simply wasn't possible to meet the owner's request. The problem was that he was doing the Web design and simply didn't know how to make Web sites compliant with FireFox.
It probably won't shock you to know that that our company went bankrupt.
Using generic numbered identifier names
At my current work we have two rules which are really mean:
Rule 1: Every time we create a new field in a database table we have to add additional reserve fields for future use. These reserve fields are numbered (because no one knows which data they will hold some day) The next time we need a new field we first look for an unused reserve field.
So we end up with with customer.reserve_field_14 containing the e-mail address of the customer.
At one day our boss thought about introducing reserve tables, but fortunatly we could convince him not to do it.
Rule 2: One of our products is written in VB6 and VB6 has a limit of the total count of different identifier names and since the code is very large, we constantly run into this limit. As a "solution" all local variable names are numbered:
Lvarlong1
Lvarlong2
Lvarstr1
...
Although that effectively circumvents the identifier limit, these two rules combined lead to beautiful code like this:
...
If Lvarbool1 Then
Lvarbool2 = True
End If
If Lvarbool2 Or Lvarstr1 <> Lvarstr5 Then
db.Execute("DELETE FROM customer WHERE " _
& "reserve_field_12 = '" & Lvarstr1 & "'")
End If
...
You can imagine how hard it is to fix old or someone else's code...
Latest update: Now we are also using "reserve procedures" for private members:
Private Sub LSub1(Lvarlong1 As Long, Lvarstr1 As String)
If Lvarlong1 >= 0 Then
Lvarbool1 = LFunc1(Lvarstr1)
Else
Lvarbool1 = LFunc6()
End If
If Lvarbool1 Then
LSub4 Lvarstr1
End If
End Sub
EDIT: It seems that this code pattern is becoming more and more popular. See this The Daily WTF post to learn more: Astigmatism :)
Back in my C++ days we were not allowed to use ==,>=, <=,&&, etc. there were macros for this ...
if (bob EQ 7 AND alice LEQ 10)
{
// blah
}
this was obviously to deal with the "old accidental assignment in conditional bug", however we also had the rule "put constants before variables", so
if (NULL EQ ptr); //ok
if (ptr EQ NULL); //not ok
Just remembered, the simplest coding standard I ever heard was "Write code as if the next maintainer is a vicious psychopath who knows where you live."
Hungarian notation in general.
I've had a lot of stupid rules, but not a lot that I considered downright strange.
The sillyiest was on a NASA job I worked back in the early 90's. This was a huge job, with well over 100 developers on it. The experienced developers who wrote the coding standards decided that every source file should begin with a four letter acronym, and the first letter had to stand for the group that was responsible for the file. This was probably a great idea for the old FORTRAN 77 projects they were used to.
However, this was an Ada project, with a nice hierarchal library structure, so it made no sense at all. Every directory was full of files starting with the same letter, followed by 3 more nonsense leters, an underscore, and then part of the file name that mattered. All the Ada packages had to start with this same five-character wart. Ada "use" clauses were not allowed either (arguably a good thing under normal circumstances), so that meant any reference to any identifier that wasn't local to that source file also had to include this useless wart. There probably should have been an insurrection over this, but the entire project was staffed by junior programmers and fresh from college new hires (myself being the latter).
A typical assignment statement (already verbose in Ada) would end up looking something like this:
NABC_The_Package_Name.X := NABC_The_Package_Name.X +
CXYZ_Some_Other_Package_Name.Delta_X;
Fortunately they were at least enlightened enough to allow us more than 80 columns! Still, the facility wart was hated enough that it became boilerplate code at the top of everyone's source files to use Ada "renames" to get rid of the wart. There'd be one rename for each imported ("withed") package. Like this:
package Package_Name renames NABC_Package_Name;
package Some_Other_Package_Name renames CXYZ_Some_Other_Package_Name;
--// Repeated in this vein for an average of 10 lines or so
What the more creative among us took to doing was trying to use the wart to make an acutally sensible (or silly) package name. (I know what you are thinking, but explitives were not allowed and shame on you! That's disgusting). For example, I was in the Common code group, and I needed to make a package to interface with the Workstation group. After a brainstorming session with the Workstation guy, we decided to name our packages so that someone needing both would have to write:
with CANT_Interface_Package;
with WONT_Interface_Package;
When I started working at one place, and started entering my code into the source control, my boss suddenly came up to me, and asked me to stop committing so much. He told me it is discouraged to do more than 1 commit per-day for a developer because it litters the source control. I simply gaped at him...
Later I understood that the reason he even came up to me about it is because the SVN server would send him (and 10 more high executives) a mail for each commit someone makes. And by littering the source control I guessed he ment his mailbox.
Doing all database queries via stored procedures in Sql Server 2000. From complex multi-table queries to simple ones like:
select id, name from people
The arguments in favor of procedures were:
Performance
Security
Maintainability
I know that the procedure topic is quite controversial, so feel free to score my answer negatively ;)
There must be 165 unit tests (not necessarily automated) per 1000 lines of code. That works out at one test for roughly every 8 lines.
Needless to say, some of the lines of code are quite long, and functions return this pointers to allow chaining.
We had to sort all the functions in classes alphabetically, to make them "easier to find".
Never mind the ide had a drop down. That was too many clicks.
(same tech lead wrote an app to remove all comments from our source code).
In 1987 or so, I took a job with a company that hired me because I was one of a small handful of people who knew how to use Revelation. Revelation, if you've never heard of it, was essentially a PC-based implementation of the Pick operating system - which, if you've never heard of it, got its name from its inventor, the fabulously-named Dick Pick. Much can be said about the Pick OS, most of it good. A number of supermini vendors (Prime and MIPS, at least) used Pick, or their own custom implementations of it.
This company was a Prime shop, and for their in-house systems they used Information. (No, that was really its name: it was Prime's implementation of Pick.) They had a contract with the state to build a PC-based system, and had put about a year into their Revelation project before the guy doing all the work, who was also their MIS director, decided he couldn't do both jobs anymore and hired me.
At any rate, he'd established a number of coding standards for their Prime-based software, many of which derived from two basic conditions: 1) the use of 80-column dumb terminals, and 2) the fact that since Prime didn't have a visual editor, he'd written his own. Because of the magic portability of Pick code, he'd brought his editor down into Revelation, and had built the entire project on the PC using it.
Revelation, of course, being PC-based, had a perfectly good full-screen editor, and didn't object when you went past column 80. However, for the first several months I was there, he insisted that I use his editor and his standards.
So, the first standard was that every line of code had to be commented. Every line. No exceptions. His rationale for that was that even if your comment said exactly what you had just written in the code, having to comment it meant you at least thought about the line twice. Also, as he cheerfully pointed out, he'd added a command to the editor that formatted each line of code so that you could put an end-of-line comment.
Oh, yes. When you commented every line of code, it was with end-of-line comments. In short, the first 64 characters of each line were for code, then there was a semicolon, and then you had 15 characters to describe what your 64 characters did. In short, we were using an assembly language convention to format our Pick/Basic code. This led to things that looked like this:
EVENT.LIST[DATE.INDEX][-1] = _ ;ADD THE MOST RECENT EVENT
EVENTS[LEN(EVENTS)] ;TO THE END OF EVENT LIST
(Actually, after 20 years I have finally forgotten R/Basic's line-continuation syntax, so it may have looked different. But you get the idea.)
Additionally, whenever you had to insert multiline comments, the rule was that you use a flower box:
************************************************************************
** IN CASE YOU NEVER HEARD OF ONE, OR COULDN'T GUESS FROM ITS NAME, **
** THIS IS A FLOWER BOX. **
************************************************************************
Yes, those closing asterisks on each line were required. After all, if you used his editor, it was just a simple editor command to insert a flower box.
Getting him to relent and let me use Revelation's built-in editor was quite a battle. At first he was insistent, simply because those were the rules. When I objected that a) I already knew the Revelation editor b) it was substantially more functional than his editor, c) other Revelation developers would have the same perspective, he retorted that if I didn't train on his editor I wouldn't ever be able to work on the Prime codebase, which, as we both knew, was not going to happen as long as hell remained unfrozen over. Finally he gave in.
But the coding standards were the last to go. The flower-box comments in particular were a stupid waste of time, and he fought me tooth and nail on them, saying that if I'd just use the right editor maintaining them would be perfectly easy. (The whole thing got pretty passive-aggressive.) Finally I quietly gave in, and from then on all of the code I brought to code reviews had his precious flower-box comments.
One day, several months into the job, when I'd pretty much proven myself more than competent (especially in comparison with the remarkable parade of other coders that passed through that office while I worked there), he was looking over my shoulder as I worked, and he noticed I wasn't using flower-box comments. Oh, I said, I wrote a source-code formatter that converts my comments into your style when I print them out. It's easier than maintaining them in the editor. He opened his mouth, thought for a moment, closed it, went away, and we never talked about coding standards again. Both of our jobs got easier after that.
At my first job, all C programs, no matter how simple or complex, had only four functions. You had the main, which called the other three functions in turn. I can't remember their names, but they were something along the lines of begin(), middle(), and end(). begin() opened files and database connections, end() closed them, and middle() did everything else. Needless to say, middle() was a very long function.
And just to make things even better, all variables had to be global.
One of my proudest memories of that job is having been part of the general revolt that led to the destruction of those standards.
An externally-written C coding standard that had the rule 'don't rely on built in operator precedence, always use brackets'
Fair enough, the obvious intent was to ban:
a = 3 + 6 * 2;
in favour of:
a = 3 + (6 * 2);
Thing was, this was enforced by a tool that followed the C syntax rules that '=', '==', '.' and array access are operators. So code like:
a[i].x += b[i].y + d - 7;
had to be written as:
((a[i]).x) += (((b[i]).y + d) - 7);

Resources