views:

2253

answers:

55

We've all been there (usually when we are young and inexperienced).

Fixing it properly is too difficult, too risky or too time-consuming. So you go down the hack path. Which hack from your past are you most ashamed of, and why? I'm talking about the ones where you would be really embarrassed if someone could attribute the hack to you (quite easily if you are using revision control software).

One hack per answer please.

Mine was shortly after I started in my first job. I was working on a legacy C system, and there was this strange defect where a screen view failed to update properly under certain circumstances. I wasn't familiar with how to use the debugger at this time, so I added traces into the code to figure out what was going on. Then I realised that the defect didn't occur anymore with the traces in the code. I slowly backed out the traces one-by-one, until I realised that only a single trace was required to make the problem go away. My logic now would tell me that I was dealing with some sort of race-condition or timing related issue that the trace just "hid under the rug". But I checked in the code with the following line, and all was well:

printf("");

Which hacks are you ashamed of?

+2  A: 

I was young, inexperienced and way behind budget and deadlines...

I needed to add a feature to an accounting system I had written, this feature was supposed to pull a list of unique checks from an array of payments (One check could contain money for more than one payment).

I wrote this:

Dim UniqueCheckNum(1000)
Dim TotalUniqueChecks
TotalUniqueChecks = 0

for i = 0 to TotalUniqueChecks
 for j = 1 to TotalElem
  if NOT StCheckNum(j) = UniqueCheckNum(i) then
   UniqueCheckNum(TotalUniqueChecks) = StCheckNum(j)
   TotalUniqueChecks = TotalUniqueChecks + 1
  end if
 next
next

To this day, I don't know why I did it that way, especially considering the strange way I abused the for statement...but it works, and the system is still production, handling payments everyday...

This is my favorite snippet of WTF the code, and I've always kept a copy of that file around.

FlySwat
I tried that stunt once "in time out of mind" but VB 6 wouldn't cooperate ...
Booji Boy
Weird. That probably works only on a specific version of VB. Most of the time modifying the loop terminator does nothing.
Joshua
+2  A: 

In my teenage days, I was writing a code-golfed biorhythms calculator in x86 assembly. As x86 programmers know, the shortest way to divide by small numbers is to use the aam instruction (see my fizzbuzz solution for an example of its use).

Well, aam's argument is an immediate operand. So, in order to loop through with the various divisors (23, 28, 33), my code incremented the immediate operand by 5 each time. Yes, self-modification of the running code. Luckily in DOS code, this is all very kosher. :-P

Chris Jester-Young
only in real mode, not protected mode though! (right? or am I smoking something)
Booji Boy
Sorry, I did mean real-mode DOS code. :-) (Not any of that DOS extender business.)
Chris Jester-Young
no problem, just making sure I didn't mis-remember that. We are showing our age ...
Booji Boy
IIRC the immediate operand wasn't documented as such, but rather as a continuation of the opcode. A consequence of this was that a value of other-than-10 wouldn't work on some non-Intel x86 chips.
Jeffrey Hantin
+60  A: 

In a Windows95-era game, I wrapped the mainloop in an exception-handler. Any time the game crashed, for whatever reason, I popped up message purportedly from Windows, with some impenetrable-looking message designed to put the blame squarely on the OS's shoulders.

Now I'm intrigued, which game?
Brad Gilbert
I knew it, Tribes 2?
Dan Blair
No comment :) But no, not Tribes 2.
That's beautiful!
Michael Burr
And thus the hatred for Windows and MSFT begun. LOL
Jon Limjap
No wonder "safe languages" got such traction, but still ... some hardcore C/C++ folks still don't get why they are better :) (in many aspects)
Pop Catalin
That's hilarious, well done.
Benson
"Which game?" All of them did that. :)
Bill the Lizard
+14  A: 
/* printf("%s",meaningoflife); */ 
printf("%d",42);
Onorio Catenacci
lol... HHGTTG, Answer to Life, the Universe, and Everything -> http://en.wikipedia.org/wiki/Answer_to_Life,_the_Universe,_and_Everything
Leon Tayson
I figured this audience would appreciate that joke. :-)
Onorio Catenacci
+14  A: 

Hard Coded account numbers and customer names into a COBOL program so it would pass testing, then I worked ALL NIGHT to get the COBOL code to read the IMS database correctly and display the data properly (not hard coded obviously!). What still baffles me to this day is how the testing department (we had a dedicated group of software testers) looked at the screen output from my program and let is "pass".

Knowing it would fail in production that next day, I came back after dinner and worked until 5am! I was 23 and 1/2 a lifetime ago!

Optimal Solutions
+3  A: 

When I first built an ASP.NET AJAX site I wrapped the entire page body in an UpdatePanel, it was a massive form (comprising of 20 - 40 controls).

Oh the humanity...

Thankfully I did actually learn what AJAX was all about and the potential evils of the UpdatePanel

Slace
is that what caused the power failure across the northeast back when? :-)
Optimal Solutions
+6  A: 

5 years ago I had to write the business logic behind a front end GUI written by another programmer in VB.NET 1.1 (He was the employee and I was the consultant ...[sigh]) He had created the front end using a hodge-podge of nested and poorly tested user controls. I just could not get a parent control to get the focus at certain point once the focus was in child control. Soooo, I used cough sendkeys{tab} to fix the issue... The app is still in production w/ the hack running on citrix farm of three terminal servers w/ 120 or so win-terminals ;D

Booji Boy
+3  A: 

In the days before AJAX, Internet Explorer exposed a method called ShowModalDialog. Working in classic ASP, I figured out a technique that called ShowModalDialog with an ASP page as the URL. This page would query the database and response.write the information out in the form of a client-side javascript object that was returned when the modal browser window was automatically closed.

If the read operation took a bit of time, the modal browser window could even be made to show a progress bar.

With this technique I was able to update page contents without a full reload, a la AJAX.

EDIT: I just looked this stuff up, and showModalDialog() premiered in IE 4 in 1997, and XMLHttpRequest (aka AJAX) came out with IE 5 in 1999. But the IFrame sort of beat them all in 1996.

I'm ashamed because I came up with my AJAX-like hack in 2000, more than a year after AJAX premiered.

MusiGenesis
hell yeah, I wrote a whole system using "xml data islands" and xmlhttprequest. it was well before it's time.
TheSoftwareJedi
I did a similar thing before AJAX, what I loaded an iframe of data then rad the content of iframe and change the current page :) it was almost like AJAX before AJAX. I thought that was so clever.
dr. evil
+96  A: 

How to hide HTML source.

Preparing a product demo, the boss required that the source code of the web page would not be visible when the user right-clicked in the browser and selected "view source", because he tought that "probably" someone would steal the code and duplicate the product.

So, I put in the html file about 100 blank lines and then all the content, so when my boss right-clicked the page and selected "view source" he only saw an aparently empty file. Fortunately, he didn't notice the diminute scroll bar of the file viewer indicating that the "empty file" had more content.

German
that's brillant!
nickf
That's a smart boss you had there :)
nickf: Boss was probably called Paula. :-)
Chris Jester-Young
Priceless! Brillant solution for a brillant boss.
Esteban Brenes
Now that is a classic!
Richard Ev
Quirks mode in ie6 but?
alex
Does your boss have pointy hair?
Chris Lutz
Is it just me, or does it sound to anyone else like German is actually not ashamed of this hack at all? ;)
Dan Tao
German built http://autotrader.com/ !
MiseryIndex
This reminds me so much of "The system is down" videos
Joe Philllips
A: 

Well, this hack comes because of the tight deadline. I guess all the hacks come out this way. Anyway, I was working on a school project and the next day the students must get an exam but they are not supposed to start the exam until 8:00 AM next day. So, I just hard coded the line:

if(date is less than 8:00 datetime) then tell the student that it is not time to start the exam.

Sometimes the working software is more important then a hack.

azamsharp
Hard-coding a constraint isn't really a hack, IMO. It's ugly, but not a hack.
Brian
A: 

There's this one I used to do (and I see done all the time) to convert a number to a string in Java:

int n = 12345;
//...
String s = "" + n;

Of course, this is better done like this:

int n = 12345;
//...
String s = Integer.toString(n);

Heck, for all I know the Java compiler may have a special case for empty-string plus primitive that makes this hack just as efficient. But if not, this method requires creating a StringBuilder object behind the scenes, which is just unnecessary.

Kip
If your n is constant (using your example of 12345), it gets turned into the string constant "12345". If it's not constant, then yes, a StringBuilder is used (tested with OpenJDK 7). Hmmm....
Chris Jester-Young
Holy Crap it works in C#!
Lucas McCoy
+5  A: 

There's this one I'm ashamed to say I've done. Given code like this:

RC = doSomethingThatShouldNeverFail();
if(FAILED(RC))
{
  if(pObj1) { delete pObj1; pObj1 = NULL; }
  if(pObj2) { delete pObj2; pObj2 = NULL; }
  TRACE << "Failed to do something" << endl;
  ErrorStack.Push("Err Message");
  return E_FAIL;
}

Since doSomethingThatShouldNeverFail() should never fail, no test case covers the lines inside the statement. This makes code coverage suffer. Instead of writing a test case that does fail (if that is even possible), you can in-line the whole if statement, like this:

RC = doSomethingThatShouldNeverFail();
if(FAILED(RC)) { if(pObj1) { delete pObj1; pObj1 = NULL; } if(pObj2) { delete pObj2; pObj2 = NULL; } TRACE << "Failed to do something" << endl; ErrorStack.Push("Err Message"); return E_FAIL; }

Now there are no lines of code which aren't covered, but you've got this really ugly line of code that is hundreds of characters long.

Kip
Haha. I would hate you :)
Joe Philllips
A: 

I needed to read the file listing of pkziped files in a Quake III launcher app I wrote something like 8 years ago. This would let me get the maps included in the pak files installed in the system.

I ended up patching in the source from the open source unzip executable by renaming its main and then changing the code to write the file listing to a global buffer. I then called the unzip_main with the pak file name and the parameter to list the contents in the argc and argv parameters.

Much later, I saw that there was an open source library that probably would have been better and easier.

crashmstr
This makes me laugh for some reason.
phkahler
+2  A: 

This was with Java and I was actually working as a junior Java developer.

Long long time ago I stuffed various objects in a list. But objects were not representing same class... If I remember right the reason for this was to allow method to return multiple objects.

List funkyMethod() {
    List resultList = new ArrayList();
    resultList.add(new BusinessItem());
    resultList.add(new StatusBean("2", "ok"));
    return resultList;
}

Accessing was then serious casting:

StatusBean status = (StatusBean)funkyMethod.get(2);

Horrible for team mates but luckily I rewrote it afterwards. I wonder how come my mentor missed that...

Petteri Hietavirta
+9  A: 

In basic (ashamed already), but at least was for a C64.

If you have lines like this:-

1000 GOSUB 2000
1010 RETURN

Then you can save a line with this:-

1000 GOTO 2000

Since the RETURN somewhere after line 2000 will pop stuff off the stack. You save yourself a line of code and a couple of cycles.

WW
*blink* That's standard tail-call optimization. First time I've seen it in BASIC, though.
Jeffrey Hantin
+16  A: 

I got a PHP gig on craigslist to convert a site from PHP4 to PHP5. I finished the job in under 5 minutes by placing this in the header:

extract($_REQUEST);
Kevin
Before anybody screams "insecure", the PHP4 code was probably armored against the insecurity this appears to create.
Joshua
register_globals reloaded, huh?
poke
A: 

My biggest hack so far has been when writing some music in Lilypond. I wanted a horizontal bracket over some music, so I hacked it out of the ottavation bracket. I just removed the ottavation text and set it to not transpose by an octave...

startBracket =
{
    \ottava #1 %sets a one octave transposition
    \set Staff.ottavation = #""  %this gets rid of the ottavation text
    \set Staff.middleCPosition = #0   %this puts middle C back where it came from
                                      % ie it "untransposes" it
}
masher
Let me recommend http://lilypond.org/doc/v2.13/Documentation/user/lilypond/Outside-the-staff#Analysis-brackets and http://lilypond.org/doc/v2.13/Documentation/user/lilypond/Writing-text#Text-spanners :)
thSoft
+24  A: 

In the first year of my Software Engineering course at the Uni I had to write some short Java programs, which I would then submit to an automated marking system. I noticed that what the system did was: run my code, compare the result with expected result and then produce a response like:

Got: 6
Expected: 7

The task at hand was not exactly too straight-forward, and English not being my first language, I couldn't 100%-positively say that I understood the task correctly. Instead of worrying about how to write the code so that it produces the right result, I changed my code to:

return 7;

And in it went and passed all checks. Got me a nice 100% in coursework for that module...

The dirties hack ever :D ;)

(No, not really, I do a lot of quick-and-dirty hacking... :D)

EDIT I just realised the exact wording of the question was "[...] are you most ashamed of?" and I must admit, I am not ashamed of this hack, no-no, not the least bit. I'm actually quite proud of it :)

Peter Perháč
Didn't your teacher check that code?
Arnis L.
In my experience, most don't bother as long as your code looks like it works.
MiseryIndex
It did work. It returned 7 like the test required :)
Joe Philllips
Wow. My university had a similar testing system for the assignments that just checked output, but it would at least run the same program several times with different inputs - nothing should have returned 7 every time. Also, a student (myself, for a time) was paid to grade the code.
Jeff Barger
I now know a few people who are working hard on re-writing and improving this automated marking system. Yesterday I told them about this hack of mine and they did not seem to care much. Certainly, the approach Jeff Badger's uni takes is much more fool-proof. But they don't seem to worry their heads too much about that at the Brighton Uni.
Peter Perháč
Yep, you didn't have me writing that autochecker. I wrote an autochecker for an assignment when I was a TA. The students got *one* version, and I got *another* version to ensure that clever chaps like you didn't cheat.
Paul Nathan
+1  A: 

As the Database Administrator was away on holiday's, management wanted a feature ASAP.

We ended up implementing a flag on a single Id in compiled code for an c# events system.

if (Id == 141) {
    //Do Some Action
}
Elijah Glover
+74  A: 

Didn't use it personally, but I think the fast inverse square root function in the Quake 3 source code is an awesome hack:

float InvSqrt(float x) {
    float xhalf = 0.5f*x;
    int i = *(int*)&x;
    i = 0x5f3759df - (i>>1);
    x = *(float*)&i;
    x = x*(1.5f - xhalf*x*x);
    return x;
}

The article explains how the function works and how it originated.

Ayman Hourieh
That's up there with Duff's device, plus a Master's in Applied Math.
Jeff Leonard
The thing I find fascinating about that is that noone knows why 0x5f3759df was chosen. It's voodoo.
NeilInglis
Genius. For those who are interested, http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
Nick D
Worth adding the comment that almost all modern cpus with the right compiler optimizations outperform this in FP now. It's still a wonderful historical example though
ShuggyCoUk
I will never understand how such subjective "vote me up" questions could have an accepted answer. It's an artifact of SO's forcing people to accept answers by providing bonuses for it.
Eli Bendersky
I prefer the commented version, with comments like "// evil floating point bit hacking" and "// WHAT THE FUCK?"
Chris Lutz
Here's an article about it: http://betterexplained.com/articles/understanding-quakes-fast-inverse-square-root/
Andreas Grech
this function saved my iPhone app...
Ben Gotow
It took me a few minutes to realise that by inverse square root function people mean f(x) = x^-(1/2) and not actually the inverse function of the square root function, which would be f(x) = x^2. It was obvious from the code that it wasn't computing a square, but whatever it was computing was unclear.
Joren
The hack is brilliant. But the article is wrong in claiming that's Newton-Raphson. That's a non-iterative function, and N-R is an iterative technique that can't be guaranteed to give you a good answer in one iteration. I would guess it's more something akin to a polynomial or rational function (ratio of two polynomials), which are often good at this kind of thing. And once you know what the approximation technique is, I'm sure the reason for 0x5f3759df (actually, its equivalent as a float) would be obvious.
Bob Murphy
That paper suggests using 0x5f375a86 instead... (just placing this comment because one day I might need this, so I'll come back to stackoverflow and read my own comment, so I'll be able to investigate and eventually come up with a good solution.
luiscubal
+20  A: 

Apparently an argument about to or not to use hungarian notation went on far too long and someone decided to make a compromise. The following hack was implemented for most members in the object hierarchy and allowed for "the best of both worlds"

class Foo { 
public:
  union {
    const SomeType* cstNamePtr;
    const SomeType* Name;
  };
}

This allows both hungarian and non-hungarian usage

Foo* pFoo = GetSomeFoo();
pFoo->cstNamePtr;
pFoo->Name;

Note: I am not the originator of this hack, just the presenter :)

JaredPar
I have seen this hack used before as well. However it was to shorten (not change) an overly verbose API, which had methods very similar to sentences, like int computeNumberOfCharactersInStringBuffer(). We thought about a macro to simplifiy it, but that's just too powerful an hacky. So we used the union trick to make a numChars() name alias. The hack of course now means there were two ways to call the same method but overall we were happy and didn't regret it.
SPWorley
@Arno can you show exactly how to do this?
rlbond
@rl, we just made an inline method that just called the "Real" method.
SPWorley
I giggled like a girl reading that.
Paul Nathan
+61  A: 

I don't know if the comment switch trick can count as a hack but sometimes it's very convenient for testing 2 pieces of code:

/*  <---
line1
/*/
line2
//*/ 

//* <---
line1
/*/
line2
//*/
Nick D
I usually use #if 0 #else #endif blocks for things like this. Just change the 0 to make the blocks flip :)
laalto
great :) -
Nick D
Wow, this is really cool! I have used a related trick: /* Code /**/ and to uncomment: Code /**/
rlbond
I have done that
Daniel Moura
I love that one.
GameFreak
I was about to try that in the project I'm working on, then I realized it was VB.
Cory Larson
My mind is blown.
aehiilrs
I do this all the time.
mattbasta
+1. I still use this regularly (though I would not commit code to source control in that state.)
finnw
Sadly this doesn't work in every language, depending on how the comment parser works..
poke
@finnw, @poke: I have the bad habit to commit such code :) The git gui interface on Windows has problem on highlighting properly such code. I use this trick in C++ and I never encountered any other IDE/editor/compiler having the same problem.
Nick D
+2  A: 

It a templated collection class, I once ran across the following.

template <typename T>
class SomeCollection { 
  void Add(T* pValue) {
    ...
    memcpy(&someInternalNode, pValue, sizeof(T));
  }
};

I found this when I attempted to use a type which depended on value semantics in conjunction with this collection. My best guess is they ran into issues when doing a direct assignment (which is an indication BTW that there is a bug in the usage)

JaredPar
+8  A: 

The C++ hack which caused me the most personal pain to undo was the following

#undef new

It took me roughly 2 months to figure out first why this was done and secondly to undo all of the weird code that was added to work around this issue.

JaredPar
Why was this done?
Liran Orevi
Am I missing something? new isn't a macro, so this should have no effect.
anon
Why was this in code?
rlbond
@Liran, it was done to prevent people from using new.
JaredPar
We used this once when we had to write our own memory manager - requirements were that no new memory could be allocated once the program had loaded (in an existing program). In order to do this we had to replace usages of the new operator - the best way to find them initially AND make sure that they did not sneak back into the code was to undefine new.
Shane C. Mason
@Neil, it was done on an older compiler and did have an effect. On that version of the compiler it removed new as a vialable function. You couldn't do "new Foo" anymore. What was interesting is that you could see how this hack evolved over time as the compiler got more correct. The code went to other lengths to prevent new from working.
JaredPar
+4  A: 

Visual Studio Compiler hack:

//Visual Studio Bug Workaround:
//http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=101677

//To fix undeclared identifier compiler errors, change the number lines below
//until the file compiles correctly. (This needs to be done anytime a change is made to this file)

    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
    //////////////////////////////////////: There should be 1-10 of these lines
NotDan
+5  A: 

I was working on fitting a query engine in a resource-constrained embedded environment. The expression evaluation function was essentially a highly recursive switch-case block: each expression type was a separate case and subexpressions were evaluated recursively. The problem was that the function consumed about 600 bytes of stack for each level of recursion. The embedded environment defaulted to 8kB of stack so any non-trivial expression would easily lead to crashes of all sorts.

I pulled all the variable declarations out from case blocks and crammed them in a tight union, carefully making sure the variable use patterns would not have any overlaps. At the end of this exercise, the function needed just some 24 bytes of stack. Nice optimization for a constrained environment, but certainly did not make the code easier to understand.

(I think this is not the most shameful nor awesome thing ever, but combines both aspects nicely.)

laalto
+22  A: 

Not sure I want to own up to this, but I implemented the goto and comefrom commands for Python: http://entrian.com/goto/

RichieHindle
You are an evil man. Goto is evil in the bad sense. Comefrom is evil in the good sense. Are you looking for a job? :-)
Bob Murphy
A job? No, just forgiveness. :-)
RichieHindle
http://www.geekherocomic.com/2009/08/28/the-8th-deadly-sin/ :-)
Ludwig Wensauer
+18  A: 

From http://thedailywtf.com/Comments/Illogical-Logic-Flow.aspx#266508

int x = 1;

/**++++++++++++++++++++++++++++++++++++++++++++++++++++

 ++ This is a long comment of a lot of text that     ++

 ++ had absolutely no redeeming value except that    ++

 ++ it could easily */x++/** mislead you into making ++

 ++ your eye skip right past the relevant part in    ++

 ++ the middle of the block of unending comments.    ++

 ++++++++++++++++++++++++++++++++++++++++++++++++++++*/;
GvS
I don't think this is a hack so much as it is a nightmare.
Cuga
Typically hacks have a reason to exist, even if they are ugly. I fail to see why would this so-called "hack" be useful.
luiscubal
+5  A: 

On Netburst era intel hardware the x87 floating point hardware behaved incredibly badly when presented with a double/float.NaN as an operand. Literally costing 100s of cycles to deal with it.

Since we made us of these extensively as 'safe' guard default values (to prevent a default of zero forcing a usable but 'incorrect' zero output for example) and the pre 2.0 versions of the CLR did not emit SSE for all floating point operations.

We came up with the following:

unsafe static bool IsNaN(double d)
{
    const long Mantissa = 0x000fffffffffffffL;
    const long Exponent = 0x7ff0000000000000L;
    long l = *((long*)(void*)&d);
    return (l & Exponent) == Exponent && (l & Mantissa) != 0; 
}

Nowadays this is unneeded but it was a massive performance win for us at the time.

For additional amusement the current double.IsNaN function in the framework (and many others) is:

public static bool IsNaN(double d)
{
    return d != d;
}

So we were hardly alone in making use of somewhat unintuitive behaviour

ShuggyCoUk
+4  A: 

We had a large Fortran77 code base that had used one large globally allocated array as scratch space in builds released in the 70's and 80's. Functions would return indexes into this large memory buffer as requested by various routines. I modified the code to be able to use dynamic memory by tying an "empty" Fortran array to a memory address returned from malloc (via a function written in C).

So the Fortran half looked more or less like this:

  integer iscratch(*)
  pointer (ptriscratch, iscratch)

  ptriscratch = my_malloc_wrapper_code()

This syntax (using pretty widely adopted language extensions) causes the address returned from my_malloc_wrapper_code() to be assigned to the base of the iscratch Fortran array.

Obviously there was a bit more to this where I had to write a library of C code that managed blocks of memory allocated in C and returned those addresses to the Fortran client code.

This bought us dynamic memory in Fortran77 compatible compilers (well, compilers that recognized this "integer pointer" extension -- which was all the compilers we cared about). The company was not ready to adopt Fortran90 compilers at the time, plus the legacy code base that used various offsets into the large preallocated array needed to be supported moving forward.

Rick Reynolds
A: 

I don't like having to use java reflection in order to access private members. I also don't like having to work with the java class loader. Finally, I hate using reflection to access private members of the class loader (for example, to add additional classes the Tomcat's WebappClassLoader)

MikeNereson
+4  A: 

New to programming and not understanding instance variables i wrote an app with every variable as global. that's a LOT of variables to keep track of. And the password was hardcoded in. but hey the app worked.

Seems familiar to me. :D
Arnis L.
+3  A: 

(Not really ashamed of this, but it is a big hack)

When I wrote my first game in 386 assembler, but I needed access to memory above 1Mb to store data in but still run in real mode. Back then, there was no StackOverflow, so I wasn't able to find information about EMS/XMS APIs, so I decided to roll my own version. For those who don't know, on the 8086 memory was accessed in 64Kb blocks, the block to use was defined using a segment register. The address was calculated as follows:

address = segment * 16 + offset

so, to write to display memory, you'd need the following:

mov ax,0b800h
mov es,ax
xor di,di
mov ax,0730h
mov cx,80
rep stosw ; writes ax to 80 words starting at es:di, or 0b8000h

On the 386 in real mode the above code produced the same effect. However, the internal mechanism was totally different. Instead of:

address = segment * 16 + offset

it was:

address = segment.start_address + offset

where each segment register was a structure of data that defined the segment. In protected mode, the commands:

mov ax,1
mov es,ax

would load es with the second entry in the segment descriptor table. The value of es was 1 but es.start_address was whatever was defined in the table. In real mode, the segment data was set up to mimic the 8086, so:

mov ax,0b800h
mov es,ax ; es.start_address = 0b8000h

So, in my game, to access the extra RAM I disabled interrupts, swapped to protected mode, set up the es segment to access all RAM, swapped back to real mode and enabled interrupts. Swapping between protected and real mode did not reset the internal data for the segment registers so I could then access all memory in real mode provided I didn't write to the segment register.

It still works this way today, although Intel could change the way it works as I believe it is undocumented. I don't think the will as there is probably a few apps out there that rely on this behaviour.

Skizz

Skizz
+3  A: 

This is in VBA and I gather in this crowd that's reason enough to be ashamed ;D But it's a pretty common task in Excel Automation (in C# too for that matter) to need to replace the formulas with just the results. Particularly if you are distributing the workbook outside the company. At some point I realized this could be done by assigning Range.Value to itself. Thus this:

Sheet1.UsedRange.Value = Sheet1.UsedRange.Value

Is enough to cause all formulas to become literals.

Oorang
+2  A: 

In Fortran one did not need to declare variables. They were automagicly REAL unless the name began with I, J, K, L, M or N. So to force all variables to be declared a programming standard employed the IMPLICIT statement which would modify the default of I-N for INTEGER and the rest REAL.

IMPLICIT COMPLEX

This would cause most uses of undeclared variables to produce compiler errors. Later IMPLICIT NONE was a more direct method.

C.W.Holeman II
Hence the saying "GOD is real, unless declared integer".
David Thornley
+1  A: 

I moved from a Fortran IV on RSX-11M system to VAX Fortran77 on VAX/VMS. So, I read the Fortran manual to find out about the differences. While reading it I came across the alternate return feature of Fortran which it turned out to be a standard feature not a VAX extension. I even showed it about ridiculing it and anyone who would use such a thing.

I was assigned a project to modify an in-house product MenuGraph which prompted the user for info to define the layout and contents for displaying graphs using the ISSCO DISPLAY Fortran graphics library. One of the design features allowed the user to back up to previous questions and change the answers. This was a terminal text based user interface.

In order to support the ability to back up from anywhere the code was very messy even for 1980's Fortran. Some how the alternate return popped into my mind. Beware of what you read.

    real gpa
    integer units
    character*10 name
10  type*, 'Computes grade points from GPA and units.'
20  call sdsu_ask_real (
   .    '$Enter GPA: ', !Prompt user with this.
   .    0.0,            !Minimum value user can enter.
   .    4.0,            !Maximum value user can enter.
   .    'N',            !Default not allowed (input required).
   .    gpa,            !Variable to receive user's valid input.
   .    *10,            !Previous question label.
   .    *999)           !End of input label.
30  call sdsu_ask_integer ('$Enter units attempted: ',
   .    1,
   .    500,
   .    'N', units, *20, *999)
    call sdsu_ask_string ('$Enter your name: ',
   .    1,
   .    10,
   .    'N', name, 10, *30, *999)
    type*, name, ', your grade points =', units * gpa
999 end

The starred arguments are the alternate return labels. The routines return to the first one ( 10, 20, or 30) if the user enters "^" to backup to the previous question. If the user enters "^Z" the routines return to the second alternate return (999). The normal flow is when the user enters valid data then it advances to the next line just like regular routine calls ignoring any alternate return values.

The nasty alternate return is used in this case to make the code very clean and easy to follow.

C.W.Holeman II
+3  A: 

As part of my bachelors degree we (a group of four) spend half a semester studying a program called Fhourstones, which is an integer benchmark that solves positions in the game of connect-4, as played on a vertical 7x6 board.

By default, it uses a 64Mb transposition table with the twobig replacement strategy. Positions are represented as 64-bit bitboards, and the hash function is computed using a single 64-bit modulo operation, giving 64-bit machines a slight edge. The alpha-beta searcher sorts moves dynamically based on the history heuristic. A move causing a cutoff is rewarded as many points as moves previously tried, each of which gets a -1 penalty, thus preserving total weight and avoiding renormalization (uniform penalties were found to work much better than depth dependent ones).

Although the initial assignment was only to study the techniques used and present this to our classmates, we set out to see if we could extend the program to solve 8x8 boards as well (just over the current limit). This proved troublesome as the code was highly optimized, storing a single board position inside a (Java) long.

// bitmask corresponds to board as follows in 7x6 case:
//  .  .  .  .  .  .  .  TOP
//  5 12 19 26 33 40 47
//  4 11 18 25 32 39 46
//  3 10 17 24 31 38 45
//  2  9 16 23 30 37 44
//  1  8 15 22 29 36 43
//  0  7 14 21 28 35 42  BOTTOM

For red stones on the board the numbered bit would be set to 1, for black stones to 0. By then taking the 'skyline' of the board and setting each bit above it to 1 (like a layer of snow over rooftops) the entire board position for boards up to 8x7 can be stored using 64 bits. The entire program relied on this encoding to efficiently test for a win using 8 shift/ands and 4 comparisons.

Obviously we needed something bigger if we wanted to store larger boards, but because Java does not provide a primitive 128 bit data type, we had to look at other ways to go about storing the board positions. However, any solution we tried proved to be anywhere from 25 to 100 times slower than the original, the 'best' one being BigInteger.

As the projected runtime for the original code for the larger board was already well over a day, this increase in time required was unacceptable. Determined not to let the project fail, and somehow beat the odds at finding a faster solution, I set out to create my own number monstrosity, called

IntLong

As the name implies is was an int concatenated with a long, designed to provide us with just enough bits to be able to store the 8 x 8 + 8 = 72 bits needed. Next came the problem of making these two numbers work together to represent one larger number, and implementing all the bit operations used throughout the code base. We used the int to store the higher bits, and the long to store the lower bit, with a overflow from long to int on the 60th bit. This made it trivially easy to implement the and, or and xor operations. The shift left and shift right operations were easy as long as you were careful to move the right bits over using ands and shifts. We worked around not having to implement addition, subtractions, mulitplication and division by replacing them <<, >>, & and |, which worked surprisingly well as these were only few and far between.

The real problem came when I was trying to figure out how to implement the modulo operation in a fast and accurate way, as this was used for hashing the board positions, which would happen a few million times in our application.

After two weeks of trying every possible algorithm and finding them all too slow, I was damn near ready to give up. Then it hit me that we were only ever calculating the modulo by a known large primitive number, as part of our transposition table hashing mechanism. So with that in mind I implemented the following function:

public int modulo(int divider, int shifts) {
 IntLong temp = new IntLong(this.high, 0).shiftRight(shifts);
 if (0 < temp.high)
  throw new IllegalArgumentException("IntLong.modulo(int divider): argument too small, high still " + Integer.toString(temp.high, 2));
 temp = new IntLong(0, temp.low % divider).shiftLeft(shifts);
 temp = temp.or(new IntLong(0, this.low % divider));
 return (int) (temp.low % divider);
}

It takes the divider and the number of bits in the divider as arguments, and performs the following:

  • take the higher bits in the int, and shift them shifts times to the right, ignoring the lower bits in the long
  • divide that by the divider and shift the remainder back to the left shifts times
  • take the lower bits from the long, divide them by the divider and keep the remainder
  • overlay the bits from two and three (which by now should not overlap) into one long
  • return the remainder from one final division by divider and you should have the correct result

It took me a very long time before I could finally convince myself that the end result was indeed correct, even after all my Unit tests passed flying colors. In the end it turned out to be 2.5 times faster than the BigInteger implementation (still 10 times slower than the original), but it was just enough to run our calculations in a realistic time frame.

It's the ugliest hack I've ever had to implement, but I'm also still proud about having somehow beaten the odds and saved the project. :)

Tim
So why couldn't you store an 8x8 board in one 64-bit integer?
Eric
Because of the special top row that was part of the encoding (see text). If you think about it: without a top row, there'd be no way to distinguish between the top bit being a stone or just empty..
Tim
Why did you have to use the modulo operation for hashing? Couldn't you have split it into bytes and done a table lookup for each byte?
finnw
It was part of a highly optimized algorithm, to the point that the size of the hashtable was chosen as a formula-calculated prime number.. For more info see the link at the top.
Tim
A: 

Defining two almost identical constructors in a Java class:

public class Class
{
    final private double[] data;

    public Class(double[] data)
    {
     this.data = data.clone();
    }

    private Class(double[] data, int i)
    {
     this.data = data; // no cloning
    }
}

Only later did it occur to me that I could do it in a nicer way.

quant_dev
Just so I understand... you needed to differentiate between the constructor that stores the given data and the constructor that stores a *copy* of the given data? Do you mind sharing what the nicer solution was?
Adam Paynter
Use a factory methods for the less common version, or take a boolean copy parameter.
quant_dev
+12  A: 

The worst one I ever saw was coming across a colleague's code that has something like this:

unsigned char palette[259]; // 255 + 4, just in case

I asked him about it and he said that he was having weird memory corruption issues,so by trial and error, he just added 4 bytes onto the end of the array until it all 'magically worked'

I also once worked with a guy who'd been at the company for 5 years writing c/c++ and it transpired he didn't realise that c arrays were zero-indexed!

And a few more from the games industry

A well known game on PlayStation 1 had completely run out of main memory so they started storing their 3d-models compressed into audio memory. Never sure whether this was hacking or a stroke of genius

I also saw the code to a very, very well known game that had a helicopter fly-over path hard-coded at the top of one of their files in a huge array of magic numbers

I also heard ( but can't vouch for this ) of a company storing extra data in the top two bits of code instructions

zebrabox
@Playstation game: probably both ^^
SealedSun
Those sound like very nice hacks to manage limited memory.
Paul Nathan
When calling Win32 APIs with string buffers I learned to always add at least 1 byte after being stung several times by calls that would stop writing to your buffer at the quoted number of bytes and *then* add a nul terminator. This became a habit that I applied to all "external" calls. I never again suffered from mysterious and hard-to-debug buffer overflow crashes. One of the most useful hacks ever.
Jason Williams
+1  A: 

I can't claim credit for this one, but I was looking for how to declare const variables in Python and ran across this page: http://code.activestate.com/recipes/65207/

It revolves around this: "In Python 2.1 and up, no check is made any more to force entries in sys.modules to be actually module objects."

Adam Crume
+14  A: 

From swright's blog on the old dotnetjunkies:

void SomeDumbRoutine(...)
{
  switch (a)
  {
    ...
    case 2:
      myvar = 34;
      // do some other stuff
      goto SKIP_MIDDLE_PART;
    ...
  }

  switch (b)
  {
    ...
    case "BLANK":
      myvar = -2;
      SKIP_MIDDLE_PART: myvar += x;
      ...
      break;      
    ...
  }
}

He explains:

Here is the deal. The C compiler on that system was implementing the "switch" statement as though it was a subroutine. When it hit the beginning of the switch, it pushed the address for the bottom of the switch onto the stack. Then, when it hit a "break" statement, it just poped the address off the stack. This resulted in the following sequence of events.

  1. The routine begins.
  2. The first switch is reached and the address for the bottom of that switch is pushed.
  3. The "goto" statement is hit and the program jumps into the second switch statement.
  4. The "break" statement is hit. This pops the address off of the stack. (OPPS! That's for the other switch statement!)
  5. The program jumps to the point just AFTER THE FIRST SWITCH.
  6. The program then continues on into the second switch AGAIN.

At first I thought, "Oh! They just got confused because this routine is so long. That must be causing the error." Nope. We traced through it and eventually figured out (by reading assembly code) that the person who wrote this was INTENTIONALLY using this strange behavior of the compiler!!!!

hyperslug
+2  A: 

I was working with an embedded device that incorporated a simple webserver for configuration. It didn't have a filesystem of any sort, so rather than writing and saving static HTML pages, you had to write the webpages using special tags for form elements etc.

When you built the downloadable image it had a build step which took the webpages you'd written and pre-processed them into large static C string arrays, and replaced the custom tags with dynamic code snippets.

To serve up the webpage it re-generated the HTML from the static string arrays and the code snippets.

All fine and good; the problem came when I needed to present a page with some enormous number of checkboxes on it, but depending on other configuration options some of the checkboxes would sometimes be disabled.

The normal way to do this would be to add both enabled and disabled checkboxes to the form using the custom tags, and then use the dynamic code to serve up the correct variety, but I hit the limit on the number of custom tags the pre-processor could handle.

My solution was to include just the enabled checkbox on the page as a custom tag element, but also to include two images of a disabled checkbox (one checked, one not checked) on the page as well in each location where I needed a checkbox. I then wrapped everything in HTML end-comments "-->" and used the dynamic code snippets to insert HTML open-comments "<--" in the appropriate places so that the right stuff got displayed.

Yuk, but it did do the job.

Vicky
+4  A: 

Something I just did in Java: an inner class that subclasses its outer class:

public class XmlOutputHandler
implements OutputHandler
{
    private class ListOutputHandler
    extends XmlOutputHandler
    {
        public ListOutputHandler(Element container)
        {
            super(container, _options);
        }
    }
}

This was done because the outer class is used recursively, but in the case of a list (and several other types) I wanted to add additional code to the append operation. An alternative that might be cleaner (arguable) is to extract that operation into its own class, and create decorator instances.

The only truly ugly part of this is that it's an inner class, and the *options variable comes from the outer class. That's unnecessary, and will be changed.

kdgregory
+10  A: 

I still remember Simon Tatham's method of implementing coroutines (like C#'s yield return) in C:

#define crBegin static int state=0; switch(state) { case 0:
#define crReturn(i,x) do { state=i; return x; case i:; } while (0)
#define crFinish }

int function(void) {
    static int i;
    crBegin;
    for (i = 0; i < 10; i++)
        crReturn(1, i);
    crFinish;
}
Dour High Arch
Yes!!! I was just reading this code - what a freaking nightmare (and surprising given that I think the resulting product - PuTTY - is actually very good).
macbutch
A: 
jQuery.noConflict( extreme );
adardesign
A: 

In C, using fscanf instead of fgets:

fscanf(fileptr, "%[^\n]%*c", string);

Why? stupidity.

smcameron
+11  A: 

Checkboxes in Excel and .Net ReportViewer are exceedingly complex to implement, so I just change the font of a cell or TextBox to "Wingdings 2", in which the capital letter P is a checkmark. I've yet to have problems with it....

Joey
I do this in Crystal Reports to show a unchecked and checked box in a block of text.
Mike C.
This kind of stuff is why I lurk around here, lol. Thanks for the tips.
gmagana
+1. I've done the same
finnw
+4  A: 

My stupidest hack was a workaround for a stupid compiler bug.

For Mac programmers about 1987, Lightspped C was the C compiler of choice. It had a built-in hack where if you invoked certain MacOS system calls, they didn't actually emit the correct machine code. No, they built the call on the stack and jmp'd to it. And it worked fine on the 68000.

Then Apple released the Mac II, and it had this fancy 68020 with a thing called a 256 byte "instruction cache". Sped up things like tight loops a whole lot!

Only one little problem. Say you used Lightspeed C, and it built calls A and B on the stack. If your program called B within 256 bytes of having called A... A got executed again! Whoops!

And you couldn't use the 68020 "flush the cache" instruction, because it required the 68020 be in "supervisor" mode, which crashed Mac OS.

So I flushed the cache with 256 assembly language NOPs.

Bob Murphy
A: 

Not sure if anyone answered, this but I see people add the signature of a function at the site where the function is called instead of a header file. This works, but now the signature is in two places, and nothing to check it. In C++ at least the name-mangaling would prevent it to link. In C, it'll link, and then crash at runtime -- so you just hope crash is in area of code that gets tested before the software ships. :)

zumalifeguard
+8  A: 

What about GOTO for Java? This goto implementation allows you to write something equivalent to goto(xx) where xx is a line number in the source code. So the following exemple:

 1 public class GotoDemo {
 2     public static void main(String[] args) {
 3         int i = 3;
 4         System.out.println(i);
 5         i = i - 1;
 6         if (i >= 0) {
 7             GotoFactory.getSharedInstance().getGoto().go(4);
 8         }
 9         
10         try {
11             System.out.print("Hell");
12             if (Math.random() > 0) throw new Exception();            
13             System.out.println("World!");
14         } catch (Exception e) {
15             System.out.print("o ");
16             GotoFactory.getSharedInstance().getGoto().go(13);            
17         }
18     }
19 }

Will output when running:

$ java -cp bin:asm-3.1.jar GotoClassLoader GotoDemo           
   3
   2
   1
   0
   Hello World!

Isn't that nasty?

Pascal Thivent
+2  A: 

A very neat hack in VBA and VB6 that tends to clean up complex If-Then-Else constructs is to use the Select Case Statement in this way: Caveat: This is pseudocode, and a trivial example at best - it really shines to unravel deeply nested If-Then-Else blocks

Public Sub VitalProcess(Test1 As Boolean, Test2 As Boolean, Test3 As Boolean)

  Select Case True
    Case Test1
      'do some processing for this test'
    Case (Not Test1) And Test2
      'Typical special case'
    Case Test2, Test3
      'do some alternate processing'
    Case Else
      Debug.Print "No Processing was done - check VitalProcess ", Test1, Test2, Test3
    End Select
End Sub
caving
A: 

A long time ago when I was still learning C I was having trouble getting a shell to work(I was also writing my own 16 bit OS. Yes, dumb idea while learning C). As I was looking for possible sources I just thought I would try changing char buffer[100]; to char *buffer[100].. but here is the more amazing thing. It worked. I have no idea how, but somehow the way my code was written strlen and everything just worked after that.. That doesn't make it any less shameful though(note: buffer stored a string. not an array of strings)

Also, in a C++ project I was having severe problems with having things needing to be declared before they could be(dependencies on each other).. so I worked up the skill of including a header file. Twice. It took some definite macro magic..

Also in the same project, it was a library. So the user of the library needed to implement things before it would actually link. Well, In order to prevent having a huge header file distributed with the library(over 20k iirc) with all of the internal methods and such. I worked things into a x86Lib.h and x86Lib_internal.h. If a certain macro was defined, then it knew it was building it internally and included the _internal file, else it didn't include it and changed any references to it to void * or similar.

Earlz
char* is bigger than char, so you probably made the buffer big enough for things to work.
quant_dev
+10  A: 

Using this ugly hack for iterating over an array because I back then thought it would be cool and much faster than the "usual" way (needless to say, it was neither cool nor faster).

try {
    while (true) // who needs bound checks?
        result += a[i++];
    }
catch (ArrayIndexOutOfBoundsException e) {
    // do nothing
}

For that I surely will burn in hell...

Helper Method
Interesting. I have written a variant of this (`for (;;) {try {a[size++] = newElement; break;} catch (ArrayIndexOutOfBoundsException ex) {/* enlarge array*/}}}`)
finnw
A: 

Passing a whole file (a PNG image around 4Kb long) as a command-line argument (Base64 encoded.)

finnw
+4  A: 

This is something I found some years ago, posted by a prof, which he found in a students exercise program:

bool IsNegative(int i) {
    string s = Convert.ToString(i);
    if (s.Substring(0, 1) == "-")
        return true;
    else
        return false;
}
Vash