Posts tagged “work”
Kip New job for Kip

Just a quick note for those of you who don’t follow me on Twitter or Facebook: I have accepted a new job at Verian, a small company based in Charlotte (near where I used to work) that has remained profitable even in the economic downturn.  I’ll be a “Programmer Analyst,” which is their way of saying I’ll be programming.  My manager will be a guy I worked with at Dassault (and, in fact, I don’t think I’d have found the job if it weren’t for his recommendation).  This is great news for us! :)

I’ll be starting on May 5, so Stephanie, Emma, and I are headed to Myrtle Beach Monday morning for a quick vacation while I have this last week off.  Assuming our resort isn’t on fire, of course...

Kip What to do with old business cards?

Let’s say you’re a guy that is going to be laid off from his job in, let’s say, five days.  You probably have a lot of business cards sitting around.  What are you going to do with these after the job is over?  They have your work number on it, which won’t connect to you soon, so it’s not like you can give them to anyone.  Technically they might be considered company property, but it’s not like the company will want them back (what are they going to do, hire another person with the same name and assign him your exact job title, phone number, and e-mail address?).  I suppose the Al-Gore-approved answer would be to recycle them, but that’s not fun enough for me.

The idea that I came up with?  Playing cards!  After a few hours of tedious craft work, I managed to create a complete deck of cards, complete with stick-figure face cards (including the suicidal King of Hearts).  Much to my surprise, they can be shuffled and used pretty well, although they are not water-resistant so they may not be that useful long-term.

Anyway, check out some hot photos of the result:

Business cards used as playing cards

Kip On the job hunt

When you put your resume on Monster and Career Builder, you get some strange and sometimes sketchy e-mails about jobs that have absolutely nothing to do with the skills shown on your resume.  Case in point, the following e-mail that I received today (with my own commentary added in italics):

Hello Kip,

Hi!  Do we know each other?

Are you looking for an opportunity to apply your expertise and help expand manufacturing capabilities with a company that desires to change the way the world produces glass?

Am I ever!!  I am so sick of the way glass is produced these days!

Do you desire to work with a world leader that is planning for future success and is committed to industry leadership through innovation and technology?

That was a mouthful!  But I think my answer is “yes.”  I would assume it beats working for an unknown company planning for failure and committed to industry bottom-feeding through stagnation and tradition.

[Redacted], a Fortune 500 company and the world’s leading producer of glass packaging products, is currently looking for a Combustion Engineer to join our team at our glass manufacturing facility in Winston Salem, NC.

Combustion Engineer, what is that??  Is it anything like a Software Engineer?  Because I’m really good at software engineering.

As a Combustion Engineer, your objective will be to deliver efficient & improved combustion glass conditioning systems as well as increased furnace life through proper control of fuel consumption, heating, & melting temperatures.  In addition, you will assist in the development of effective preventative maintenance programs and be an active participant in the facility safety program.

Oh OK, so it’s nothing like software engineering or anything else that is listed on my resume.  Go on.

It has been brought to our attention that you may be just the right person we are looking for!

OK, let me just stop you right here because I can see you’re wasting our time.  Two things.  One: What fool told you that?!?  Two: I don’t think you understand just how unqualified I am to hold the title of “Combustion Engineer.”  When I have to stick a match into the little hole to light a propane grill, I turn my head away and say a prayer that I will survive it.  When it lights without an explosion, I experience the thrill of life in a way that most people have to bungee jump or skydive to experience.  I am nervous anytime I am standing near the water heater in my garage.  I will move to a different pump at a gas station, or leave altogether, if I see someone talking on a cell phone while pumping.  So unless you need me to engineer combustions by writing some software which I can use from across town, I’m not the right guy.

The rest of this e-mail was not included because it got boring.

No Comments
Kip Some thoughts on programming style

Time to discuss something controversial that leads many geeks to commit acts of heinous violence.  I’m talking about programming style!

So there are three basic ways to write if/elseif/else statements in most languages with C-like syntax:

Style A

1
2
3
4
5
6
if(condition1)
  statement1;
else if (condition2)
  statement2;
else
  statement3;

Style B

1
2
3
4
5
6
7
if(condition1) {
  statement1;
} else if (condition2) {
  statement2;
} else {
  statement3;
}

Style C

1
2
3
4
5
6
7
8
9
10
11
12
if(condition1)
{
  statement1;
}
else if (condition2)
{
  statement2;
}
else
{
  statement3;
}

Personally, I go for the most readable and maintainable code, so I use Style A iff all conditions and statements are trivial (by which I mean, they are short and fit on one line).  Otherwise I use Style C.  (Which you can see, for example, in that gradient-generator source I posted a few weeks ago.)

I’ve posted on my preference for Style C over Style B before, and I’m not going to focus too much on that here today.  However, I continue to see Style B promoted as the universal, be-all end-all solution.  It is recommended by Sun for Java, and by Zend for PHP.

The argument for preferring Style B over Style A usually goes something like this:

What if you come along and add a new line?

1
2
3
4
5
if(condition1)
  statement1;
else
  System.out.println("Condition1 failed!");
  statement2;

Now statement2 gets executed everytime!

The argument makes sense from an academic standpoint, but I am pretty sure this almost never ever happens in practice.  The reason for this is that anyone who has been programming for more than a month will immediately see that this code won’t work as designed.  It is a glaring bug that jumps out at you.  It is nearly impossible to overlook!  (Again, this is all assuming that the conditions and statements are all trivial.)

Now, for the last four and a half years my job has been primarily to fix bugs in a huge body of code, very little of which was written by me.  For the last two and a half years, in particular, I’ve been the guy who looks at build traces and unit test results from the previous night.  And when there are build or test errors, I have to look at recently changed code and decide who is responsible.  This means I have seen most of the errors made by a group of about fifty or so programmers.  That is to say, real-world errors made by real programmers, not hypothetical errors that might be made by a theoretical programmer.  So I think I am reasonably well-qualified to have a strong opinion on the matter.

With that in mind, I’ve never seen an error that was due to the use of Style A for trivial statements.  I have seen some downright ugly code that used Style A inappropriately, with conditions that were ten lines long.  And I’ve seen ugly code that has braces on the if block but not the else block (or vice-versa).  And I have seen several errors in Style B or Style C that result from intermingling of tabs and spaces.  This happens because simple editors like vi and Notepad render tabs that are up to 8 characters wide (per spec, I might add), but advanced editors usually break spec in favor of user-friendliness, rendering tabs at 2 or 4 characters wide (or whatever the user sets them to).  So if code was written using 4-character tabs in Visual Studio, then new code is added by someone using spaces in vi, and this happens back and forth a few times, you get indentation that jumps all over the place.  This is where I think Style C is better than Style B, because it is easier to find the matching open-brace because usually the opening and closing braces are written by the same developer with the same indentation level, even if the code between the braces jumps all around.  Also, with Style B, at a glance the code looks like indentation is wacky, since you have to actually read the previous line (or scan to the right end of the previous line) to find out if the developer actually intended the indentation to increase there, or if someone just increased indentation because they were using a different editor.

You can tell me why you disagree with me, and I am fully aware that there will never be agreement on this point; however, I’ll continue to avoid Style B until my pay is docked for it.  Someone has to stand up for what is right.

Kip Bug report

A bug report that came in from a customer a while back:

I found a fully reproducible scenario.  But the results are not the same all the times.

I’m pretty sure those two sentences contradict one another.

Kip Some updates on our life

Lots has been going on in our lives lately, but I’ll start this post by discussing one that many of you already have heard about.  My company is closing down their Charlotte office in six months.  A few people have been offered relocation to other offices in Massachusetts, Connecticut, and France, but not many.  A lot of people will be let go in two or three months.  And a few of us are fortunate enough to be offered jobs through the entire “transition period.”  I am in that last group, which means that if I stay through the end of March I will get a pretty substantial severance package (if I leave before then, the severance payment is much smaller).  I’m not sure what we will be doing from here, but I’ll try to keep everyone updated.

In more pleasant news, I thought I’d give some updates on Emma’s development.  She has turned into quite a giggler.  There are a few things that consistently trigger this giggling.  First and foremost, holding her in front of a mirror (especially while moving her forward and backward in front of it) will always make her stop crying and start smiling and laughing.  Another way of making her laugh it so simply let her see Punky.  It doesn’t matter what Punky is doing, she can even be sleeping.  When Emma sees her, she starts laughing.

A few days ago I spent most of the morning working from home, and I got to see Emma watch her Baby Galileo DVD.  This was very interesting.  Basically, random stuff comes by while classical music plays, and occasionally they show babies playing, or they’ll have a young kid say a word like “sun” or “moon”.  It reminded me a lot of A Clockwork Orange, when they brainwashed the guy by forcing him to vidie the ultraviolence while they played Ludwig Von.  I’m not sure if Baby Galileo is trying to brainwash viewers or not, but I had a strong urge to assassinate public officials after viewing it.

In other news, Emma learned to make the “d” sound about a week and a half ago.  This means that occasionally she sits there and says “da da da da da da da da!”  I’m trying to teach her that “da da” references me, by responding to her whenever she says the phrase.  I’m not sure how well its working, because she also says “da da da da da da” when she’s looking at Punky.  We’ll see.

As far as locomotive skills, Emma’s still not able to crawl and certainly not walk yet, but she has mastered rolling over.  She’s close to being able to sit up on her own, although she’ll tilt over to one side or the other after a minute or so.  She is also very aware, in that she’ll follow people around the room, and she can figure out where people’s voices are coming from.

I guess that’s enough updates for one post.  Until next time, keep on... doing whatever it is that you do... !

Kip Code excerpt

Do programmers still need to understand pointers in this day and age?  Is Java a good programming language?  Why is there something as opposed to nothing?

Please do not indulge in heated debate pertaining to any of the above unanswerable philosophical questions.  Instead, just let me show you what can happen when someone has to program in Java without understanding two things about the Java language: 1) all parameters are always passed by value; 2) objects are basically pointers (whose address can only be modified by assignment).  Without this knowledge, you might write code like this1:

1
2
3
4
5
6
         //ABC-defect#123456 - SetChildren update currSel so we need to take bakup of
             //currSel so that after returning we can set it back to original currSel
        TreeNode tmpCurrSel = currSel;
    int result = setChildren(currSel,fullTree,0,tmpLevels);
       if (tmpCurrSel != null)
             currSel=tmpCurrSel; //ABC-defect#123456

Hint: it does not work as the developer expected it to (and obviously he never tested it after he coded it).

1 Code has been anonymized, but indentation and grammar is preserved for EnhancedRealism™.
No Comments
Kip Macrolicious

I recently came across a clever way of writing preprocessor macros, and I figured that I would share.

Let’s say that for some reason you need to write a macro: MACRO(X,Y)1.  You want this macro to emulate a function call in every way2.

Example 1: This should work as expected.

1
2
3
if (x > y)
  MACRO(x, y);
do_something();

Example 2: This should not result in a compiler error.

1
2
3
4
if (x > y)
  MACRO(x, y);
else
  MACRO(y - x, x - y);

Example 3: This should not compile.

1
2
3
do_something();
MACRO(x, y)
do_something();

The naïve way to write the macro is like this:

1
2
3
4
#define MACRO(X,Y)                       \
cout << "1st arg is:" << (X) << endl;    \
cout << "2nd arg is:" << (Y) << endl;    \
cout << "Sum is:" << ((X)+(Y)) << endl;

This is a very bad solution which fails all three examples, and I shouldn’t need to explain why.

Now, the way I most often see macros written is to enclose them in curly braces, like this:

1
2
3
4
5
6
#define MACRO(X,Y)                         \
{                                          \
  cout << "1st arg is:" << (X) << endl;    \
  cout << "2nd arg is:" << (Y) << endl;    \
  cout << "Sum is:" << ((X)+(Y)) << endl;  \
}

This solves example 1, because the macro is in one statement block.  But example 2 is broken because we put a semicolon after the call to the macro.  This makes the compiler think the semicolon is a statement by itself, which means the else statement doesn’t correspond to any if statement!  And lastly, example 3 compiles OK, even though there is no semicolon, because a code block doesn’t need a semicolon.

The solution is kind of clever, I thought:

1
2
3
4
5
6
#define MACRO(X,Y)                         \
do {                                       \
  cout << "1st arg is:" << (X) << endl;    \
  cout << "2nd arg is:" << (Y) << endl;    \
  cout << "Sum is:" << ((X)+(Y)) << endl;  \
} while (0)

Now you have a single block-level statement, which must be followed by a semicolon.  This behaves as expected and desired in all three examples.  I have noticed this macro pattern before, but I never really thought about why it was written this way.  Mainly because I don’t often write macros to begin with.

1 You should first ask yourself why you can’t just write a regular function and declare it inline, so that the compiler will do the work for you.  I’m going to assume there is some good reason why you must use a macro.
2 Every way, that is, except that it can’t return a value.  That gets much trickier and involves heavy abuse of the ?: operator, if it is even possible at all.
No Comments
Kip Doh!

I knew it would happen eventually.  I put in some code that broke our software, and it wasn’t discovered until nearly a month later, on the day the final build was scheduled.  This meant that the final build had to be delayed for a few days, which is kind of a big deal because it can affect ship date.  So lots of e-mails were circulated which featured my name—often in a red, boldface font—in various lists of actions.

Posted below is a paraphrased version of the code in question.  I’ve renamed or taken out anything that might refer to our internal codebase, and I’ve simplified a little, but not to the point that I look like a complete idiot for missing this.  The QueryInterface() and Release() stuff might look a little weird if you’re not familiar with COM+.  Or all of this will look weird if you’re not a programmer.  But odds are you’re about to stop reading if you aren’t a programmer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
LIST(IUnknown) listObjs;
Session->GetModifiedObjects(listObjs);

const int nbObjs = listObjs.Size();

if (nbObjs > 0)
{
   ObjectID** listObjIds = new ObjectID*[nbObjs];
   for (int i = 1; i <= nbObjs; i++)
   {
      ObjectID* pObjId = NULL;
      
      IUnknown* pUnknown = listObjs[i];
      IPart* pPart = NULL;
      if (pUnknown != NULL)
      {
        RC = pUnknown->QueryInterface(IID_IPart, (void **) &pPart);
        pUnknown->Release(); pUnknown = NULL;
      }
      if (SUCCEEDED(RC) && pPart != NULL)
      {
        RC = pPart->get_ObjectID(pObjId);
        pPart->Release(); pPart = NULL;
      }
      
      listObjIds[i] = pObjId;
   }
   ...
   //process listObjIds
   ...
   for (int i = 1; i <= nbObjs; i++)
   {
      if (listObjIds[i] != NULL) { delete listObjIds[i];  listObjIds[i] = NULL; }
   }
   delete [] listObjIds;  listObjIds = NULL;
}

For those of you still with me, maybe you already see the problem.  The LIST() macro in our infrastructure behaves pretty similarly to a Vector in Java: it will resize itself dynamically, check array bounds, and automatically free memory when it is destroyed.  However, because this was written long ago by guys with a Fortran background, the items in the list start at 1, whereas a C++ array starts at 0.  Also, it only works with components implementing IUnknown; plain-old-C++ objects must be handled with plain-old-C++ arrays.  In the code above, this meant I could not declare listObjIds as an object of type LIST(ObjectID*).  So I had a LIST(IUnknown) and an array of ObjectID*s, but I treated both as LISTs!  In fact, I have gotten so used to using LISTs in C++ that I completely forgot that listObjIds was an array (I guess a better variable name would have helped too).

The line listObjIds[i] = pObjId; should instead be written listObjIds[i-1] = pObjId;, since i loops from 1 to n, rather than 0 to n-1.  (Note that the line IUnknown* pUnknown = listObjs[i]; is still correct.)  So I was writing beyond the memory allocated to the listObjIds array.  And amazingly, it worked just fine in all my testing.  Most of the time, the next sizeof(void*) bytes on the heap aren’t going to belong to anyone.  But there is a chance that they are used for some other variable, whose value you would be overwriting.  This is especially more likely if memory has become very fragmented.

We run unit tests on all four operating systems we support, but only one operating system (HP-UX) was affected by this.  And since we don’t currently have any customers using that OS, it was a while before anyone looked at the traces very closely.  Unfortunately, it happens that this code was implemented in a listener that is called every single time the user saves.  So when it was discovered, it was something that had to be fixed before the final build.  We could have delivered it as a patch, but some customers are reluctant to deploy patches because that can mean shutting down production for a few hours.  Plus it doesn’t instill confidence to say we shipped broken code.  So delaying the final build for a day or two was the best option.

The worst part of it all is that it happened just before year-end performance reviews.  Doh!

Kip The Pacific Northwest

I just got back from my first ever business trip.  My company sent me to Seattle (technically Everett, WA) this week to visit our good friends at Boeing.  You may have heard, they are a little behind schedule.  But I can’t say too much about the business purpose of my trip here.  Fortunately I wasn’t flying solo, there were several others from my company (two others from the Charlotte office).  I was the only developer there; everyone else was support.  In any case, here are a few highlights in convenient bulleted form:

  • The area is pretty.  Unless you happen to hate evergreen trees, in which I guess you wouldn’t care for it.  Because there are lots of evergreens.  When you look out the window of the plane, it looks kind of like you are about to land in a Christmas tree farm.

  • The Boeing plant is big.  Really big.  The biggest building in the world by volume, as a matter of fact.  If you imagine a garage where you might get your oil changed, with about six garage doors in the building, it’s kind of like that.  Except the garage doors are big enough to hold full-sized airplanes.

  • Security is tight there.  Since they couldn’t confirm that I was a US Citizen, I got a temporary badge requiring an escort anywhere other than the conference room.  Including the bathroom.  So I had to act like a five-year-old and ask people to take me to the bathroom.

  • I got to visit my friend from the Amazon.  It was nice to catch up with you.

  • Due to a layover in Phoenix, I got to see the Grand Canyon from the sky.  I think it was the Grand Canyon anyway.  In any case, it was a large canyon somewhere north-northwest of Phoenix.

  • On the flights to Seattle, I got to experience first-class flight for my first time.  I didn’t think it was that great, until I flew coach on the way back.  Then I remembered what coach was like.

  • Most of our nation is a barren wasteland.  That’s the impression I get from thirty thousand feet.

  • It was my observation that there are no black people in Seattle.  Some quick internet searching seems to support this: only 8.44% of the population in Seattle versus 32.72% of the population in Charlotte.  That’s a pretty big difference.  And in Everett it is only 3.35%.  That was a little weird.

  • There is some kind of circular farming that they do in the flat states, where they just don’t use 21.5% of the land in a square plot.  See many examples here.  This isn’t the first time I’ve noticed this but I thought I’d mention it.  I’m not sure how it is cost effective to waste so much of your land, but since there is so much of it done I’m assuming it must be more than 21.5% more efficient for some crops than traditional farming techniques.

  • They still like grunge rock in Seattle.  At least the station I was listening to does.  In four half-hour drives (two trips to and from Peter’s house), I think I heard: 4 Nirvana songs, 3 Pearl Jam songs, 4 Foo Fighters songs, 2 Alice In Chains songs.  And then some new stuff like that terrible Finger Eleven song about clubbing.  I really hate that song.

  • It didn’t rain all week.  Garrison had the same experience when he visited.  I’m beginning to think that “it always rains in Seattle” is just a myth.

  • No signs of Sasquatch.  That also might be a myth.  But if so, then how do beef jerky enthusiasts mess with them?

I guess that’s all I’ve got to share.

RSS feeds: Kip's - Stephanie's - Both