Tag Archives: C

Seedy Tea

Years ago, C and C++ were the “bread and butter” languages I used most often for my real work.  In my job, these former lingue franche have since been relegated to extension language status.  But extending (building Windows EXEs and user exit DLLs that call out to C APIs) was one of today’s todo’s, so I was back in the C coding saddle again.

Visual C++ is my trusty default tool, but for this task, I was free to use the GNU compilers.  And that brought the opportunity to use the Eclipse CDT (C/C++ Development Tooling) for the first time.  I use Eclipse for many other languages now, so why not?  A quick install from the Helios site (Help -> Install New Software) got me started.

I already had the Cygwin GNU C tools: gcc, gdb, make, etc.  But since I needed to build standalone stuff with no Cygwin runtime pre-reqs, I installed MinGW from the Wascana project.  By adding these through Eclipse, it automatically set up my environment to use the MinGW toolchain.

After launching into code, I soon faced a variety of weird errors; for example, just trying to launch my program (Run->Run As->Local C/C++ Application) resulted in: Launch failed.  Binary Not Found.  After poking around, I found that the Build Artifact settings were configured for an oddly-named unix library.  I changed them as follows:

  • Artifact Type:  Executable
  • Artifact name: ${ProjName}
  • Artifact extension: exe
  • Output prefix:    (empty)

I left the object file suffixes as the unix-like .o‘s rather than Windows .obj‘s, since that didn’t really matter. It would be nice if the CDT were more Windows-aware when it came to default settings.  “When in Rome,” dontchaknow.

After getting past the initial problems, I found that coding, running, and debugging was very, well, Eclipse-like: a good thing.  I have more to do, and will probably encounter more hiccups, but I’m determined now to finish this cup of CDT.

Microsoft SOAP – Lather, Restart, Repeat

A friend recently asked me to add web service wrappers around some C# .NET code I had written awhile back.  Since Microsoft invented SOAP/XML, it’s not surprising that it’s easy to do in .NET: just create the ASMX file and WebService subclass (with WebService and WebMethod attributes), and .NET handles the rest.  Visual Studio (in my case, VS 2008) even provides templates and wizards to create these for you: nice things like New Web Site – ASP .NET Web Service and Add New Item – Web Service.

I drank the .NET Kool-Aid back when I built this system and constructed with layers of assemblies.  So re-use was fairly straightforward: just add calls to methods (DLL entry points) in the appropriate layer.  Here again, with “Add Reference” and using clauses, Visual Studio makes it very easy.  That is, except for the bugs.

I occasionally got the familiar “type or namespace could not be found” error.  I assumed I had messed up a reference or using clause, or had a problem with the referenced assembly or one of its children.  But every possible cure for these yielded no joy.  Intellisense recognized the references just fine, but the compile/build didn’t.  The solution?  Restart Visual Studio.

This is a recurring bug which seems to move to new areas with each new VS release or fix.  In this case, it seems to be unique to web services referencing .NET assemblies, but it may pop up in other areas.  If I did regular .NET development (like maybe for my day job), I’d keep current on releases and fix levels.  But for this quick exercise, I stuck to the familiar Windoze-land solution: take one restart and call me in the morning.

Contrast

I happened to notice that an SUnit I added today was number 1,000.  Perhaps I should get free groceries for that milestone, but it reminded me just how much and why we take xUnits and test-driven-development (TDD) for granted.  I was a bit more aware, having spent yesterday working on a customer’s C++ code which had no xUnits or test scaffolding.

It really was a study in contrasts.

For the customer’s C++ code, I found myself fighting in the Visual Studio debugger mostly with overzealous constructors and destructors (folks, just instantiate and delete objects in constructors/destructors, don’t use them for wild stuff like reading registries, calling decryption libraries, and connecting and disconnecting from databases).  But the real hassle was having to run the code-compile-link-bounce-deploy gauntlet far too many times.  Often this isn’t bad (yes, incremental compile and auto build all help), but in this case, it took a lot set-up time getting data in the state it needed to be in before calling this code, and every code change required repeating that.  That’s usually true even of hot swap JVMs.

Compare that to my SUnit-driven VA Smalltalk code.  I wrote the test case and my first stub method before I wrote the code.  I ran the test, and of course, it failed (failed big, too: red, not yellow, due to an expected message not understood exception).  I re-ran the SUnit with Debug, and started filling in the code – in the debugger.  I added methods and even an entire class that didn’t exist before I started debugging.  I inspected objects and ivars and even changed a few to guide me through crafting and whittling at the code.  I ran it again and got to yellow.  One more “code it while debugging it” pass and the test went green.

Red, then yellow, then green.  My favorite development process.

I’ll soon upgrade my Visual Studio 2008 to 2010 and look forward to the new features it offers (thank you, Microsoft for finally bundling ASP .NET MVC, and for abandoning your own JavaScript kluges and just adopting jQuery).  But, decades later, it’s still nowhere near as productive as VA Smalltalk, VisualWorks, and Pharo, where you can write the code in the debugger while the system is still running and never have to stop it.

Why haven’t we learned?

Between the Lines

Today I was asked for some quick help with additions to a customer’s C++ code running as a user exit in one of our systems.  This bit of code used sprintf to format an error message into a buffer passed in by our system.  Pretty pedestrian stuff, but it came among many surprises, one being that the code often had no regard for buffer lengths, and risked overflowing them.

The buffer was only 256 bytes because it’s used for a summary message (if there’s more to say, it should be said elsewhere, such as a log file).  256 bytes is pretty easy to overflow, particularly with additions we added, so we needed some crash protection.  snprintf would have been a quick alternative, but was not available on this platform.  So I added widths to the format specifiers, changing something like this:

sprintf(pszMessage, “SQL error in whatever, rc=%04d, SQL=%s”, rc, pSql->Stmt);

to this:

sprintf(pszMessage, “SQL error in whatever, rc=%04d, SQL=%.215s”, rc, pSql->Stmt);

To avoid magic numbers, I could have done something like:

sprintf(pszMessage, “SQL error in whatever, rc=%04d, SQL=%.*s”, rc, (BUFFER_SIZE – 40), pSql->Stmt);

And had snprintf been available, it would have been even cleaner:

snprintf(pszMessage, BUFFER_SIZE, “SQL error in whatever, rc=%04d, SQL=%s”, rc, pSql->Stmt);

Truncating a message is not ideal, but it sure beats tossing a GPF.  In this case, losing the end of the SQL statement would not be a big deal, but the message could be rearranged or additional logging added if it were.

The point is that too much C and C++ code in the wild holds too little concern for bounds checking.  Fortunately, I now code mainly in OO languages where this is not a concern – things grow as needed.  But since C and C++ (taken together) are still arguably by far the most pervasive programming languages (with new programmers on board with it every day), it’s very much relevant.  The advice is simple:

Avoid unbounded string functions.  Avoid sprintf, strcpy, strcat, strlen, and gets.  Use snprintf, strlcpy, strlcat, strncpy, strncat, fgets, and similar functions depending on availability.  If these alternatives aren’t available, use techniques like the above to avoid overflowing buffers.  When using the strn functions, remember to leave room at the end to add the null terminator (and remember to add it!)

You can find further such advice in the C Programmer’s Ten Commandments.

Back in the day, when I coded mostly in C and C++, we augmented our lint process to scan for things like strcpy, strcat, and sprintf.  Richer compiler warnings have largely taken the place of lint (with extensions lost along the way), but it’s easy enough to simply grep for these.  And the time spent staying between the lines is a small price to pay for some crash insurance.