Skip to content

Your Smallest Code Change Could be the Most Dangerous

ADMIN | 27-09-2011

This blog entry was born in spirit, a few weeks ago Friday night at about 11:30 pm, when I changed the following code (taken from ACIS).

Hexagon pattern 1

This post will discuss two aspects of my favorite programming language, C++:

  1. The difficulty refactoring it
  2. Why I enjoy it anyway

Prelude:

This blog entry was born in spirit, a few weeks ago Friday night at about 11:30 pm, when I changed the following code (taken from ACIS, but disguised a bit to protect the guilty)

code change1

into

code_change2

If it entertains you, please take a minute to see where the mistake is. Probably the first mistake is messing around with the code at 11:30 pm. But there are so many interesting things to work on, and so little time, occasionally I bend the rules. I made this change because CalculateDoHickey was a data member of SomeClass which used the count of things in m_edges to determine if it needed to do a particular calculation.

What was the problem that caused this code to access violate and unpredictably fail? I replaced the variable edges by local_edges in every place, except where I Resized the vector used for storing the DooHickeyCalculatedFromEdge data. Then I assigned to edgeData[ii++]. In the first version of the code, edgeData will always be large enough to hold a DooHickey for each element of the list edges.

Refactoring Tools:

Like most problematic bits of coding, the mistake above had a lot of causes. Because I ran the acceptance test suite about twenty minutes after making the mistake above, I quickly noticed the problem and fixed it.

The sooner you can catch a mistake, the less costly it is to fix. Logically then, the cheapest mistake is the mistake you never make. One way to avoid making mistakes is to use refactoring tools. The change I was trying to make isn’t strictly a refactoring that I know of, but it isn’t that far off either: the following steps would allow one to do it correctly.

  1. Comment out the data member edges from SomeClass
  2. Fix compile errors caused by (1) by commenting out all code dealing with edges except the code in CalculateSomethingForMyEdges. In CalculateSomethingForMyEdges, replace edges with the local variable local_edges.
  3. Restore all the stuff you commented out in step 2

Alternatively, I could have used reserve (to allocate enough memory) and push_back to add the results to the vector. If the block of memory owned by the vector is too small, push_back will correct the problem with the small cost of some extra allocations.

Usually when I run into a big problem, the best thing to do is step away from it for a few minutes to think about the big picture. Big problems often arise when you are trying to do something in a way that is basically wrong.

On the few occasions where I have used Java or C#, I have been very impressed with the refactoring and editing facilities in Eclipse and Visual Studio, respectively. Unfortunately, my mother tongue is C++. Great Java and C# tools don’t help me much. Also, watching myself code in these languages, I am not sure the result is any better.

Visual Studio 2010 is a big improvement for editing C++ over earlier versions. The header file name auto completion and red underlines when you write code that doesn’t compile make things much quicker. But it still seems like tools for C++ are cruder than some other languages. For me coding is basically a two step process: randomly pace around the building bouncing a little rubber ball I keep in my pocket, until I understand what changes I need to make. This ball bouncing may occasionally be interrupted by reading math text books or drinking caffeinated beverages. The second step after thinking thoroughly about what needs to be done is to sit down and crank out whatever code changes need to be made. As far as I can tell, the first bit is a 'right brain' dominated activity, while the second is 'left brained'. The last step involves debugging and verifying that the changes do what they’re supposed to.

The challenge here is that computers generally have a much better 'left brain' then I do. The parsers used by major I.D.E.s can very quickly parse a huge source file and find whether it is well formed in your favorite programming language.

C++ is still better:

The enhanced refactoring tools, well-thought-out designs, and garbage collection make some people recommend using some more 'modern' languages than C++. I still would rather use C++ for three reasons:

  1. Zero overhead principal. If you don’t benefit from a language feature, it shouldn’t cost you anything. With Java and C# you end up paying for garbage collection even when your program could have been written only using stack based allocations in C. Needing to make a using block to get the same benefits C++ gives by default with stack variables annoys me.
  2. C++ is to computer languages as English is to human languages. It is hard to learn, has several widely disparate origins, and you can still be widely understood if you break the rules.
  3. ACIS and CGM are written in C++. It is easier to be really good at one language then many.

C++ and a good optimizing compiler lets you write code that is almost as efficient as assembly code, but has enough high level features – support for polymorphism, templates, operator->, etc – to enhance productivity significantly over just using assembly or C.

So what do I do now?

  • Chase the compiler whenever possible: certain changes will cause things to fail to build. This is often a good way to accomplish “refactor”-like changes.
  • Look for better refactoring tools.
  • Use smart pointers/RAII to avoid garbage collection errors.
  • Do you have any suggestions?

You might also like...

c138_2_cropped
3 Min read
3D ACIS
We often focus the success of new partners, showcasing how Spatial helped with bringing a new product to market. But...
Large Tolerant  Vertex
3 Min read
3D Software Development Kits
boolean operation Boolean operations on individual bodies are common functions in 3D modeling. While simple in concept,...
3 Min read
3D Software Development Kits
In much the same way as physical design has moved from paper 2D drawings to 3D models in software, so has analysis....
4 Min read
3D InterOp
Part and parcel with model-based engineering is model translation. Because the model is now the specification, accurate...
4 Min read
3D ACIS
We are moving things around in the office here at Spatial to accommodate some new people. As a result, our marketing...
2 Min read
3D ACIS
This article shares a simple architecture which can be used to capture meta-data about the use of ACIS APIs in your...
1 Min read
3D ACIS
How To Create an Ellipsoid using 3D ACIS The 3D analytics supported directly in 3D ACIS include: sphere, block,...
2 Min read
3D ACIS
Basically, there are two priorities when using a software component, particularly a 3D modeling kernel: Does it do what...
1 Min read
3D ACIS
A geometry kernel is a big thing. It’s a huge thing. Maybe even big enough to see from space. By most accounts, even...
1 Min read
3D ACIS
My comrades and I did a performance analysis of Intel’s Hyper Threading Technology (HTT), using thread-safe ACIS and...
3 Min read
3D ACIS
In earlier posts I’ve written a lot about the various approaches to multiprocessing and the potential benefits. What I...
2 Min read
3D ACIS
The challenges of a major software release are not unique to Spatial. And like other organizations, the launch process...
5 Min read
3D ACIS
We’ve known for a long time that the integrity of B-rep data plays a major role in the success of downstream modeling...
3 Min read
3D ACIS
Answer: when it’s a 'HappyPathPoint'.
1 Min read
3D ACIS
To finish up this series of posts; what Gregg's post described happened a few years ago. Since that first team room,...
4 Min read
3D ACIS
This post will discuss two aspects of my favorite programming language, C++:
2 Min read
3D ACIS
Way back in the Dark Ages of the mid-90s, I used to read a newsgroup called comp.lang.c++. You can tell this was the...
7 Min read
3D ACIS
Here’s a subject to which everyone can relate in one way or another: growable arrays. An array is a contiguous memory...