Make your Source Code more Readable When Passing a Boolean.

Suppose you have a C++ function declared as follows:

void UpdateDisplay(bool WithDelay);

and somewhere later you want to use this, calling it without the delay.

You could write:

UpdateDisplay(false);

But a simple way to make your source code more readable (and hence more maintainable by yourself and your team in the future) is to write:

const bool WithDelay{false};
UpdateDisplay(WithDelay);

When you compile this code for release the local variable “WithDelay” will be optimised away so this improvement to source code readability incurs no performance cost penalty.

Updating from Paradox – Handling field names containing # symbol.

I was asked to upgrade an old database system that used the BDE to interface to Paradox tables to FireDAC and MS Access.

The first job was to use FireDAC to read the Paradox tables and then move the code across to equivalent MS Access tables.

I ran into a problem because some of the paradox tables had the # symbol as part of their field names (for example “House#” for house numbers in an address). Another problem was use of the field name “Date” which caused problems as it was interpreted as an SQL type name.

FireDAC and the ODBC bridge to the paradox tables didn’t seem to handle these names very well. In particular it was impossible to update the field contents with new values.

My working solution was to use the TFDBatchMove, TFDBatchMoveDataSetReader and TFDBatchMoveDataSetWriter components to move the contents of the paradox tables into the equivalent tables in MS Access.

The TFDQuery used as the datasource for the TFDBatchMoveDataSetReader contained the following SQL statement:

SELECT “House#” as HouseNum, StreetName, Town, City, “Date” as DateEntered FROM ADDRESS

Notice the “House#” and the “Date” field names in the paradox table being in inverted commas and being renamed as part of the query, ready for the batch data move.

Making Wrong Code Look Wrong

Here’s a very good article which discusses a coding design principle “Making wrong code look wrong”.

Understanding the contents of this article will make any C++ or Delphi programmer write better code.

Making Wrong Code Look Wrong – Joel Spolsky on Software.pdf

Author Joel Spolsky is a great thinker on how to write good code.

As a C++ programmer I do feel I have to take issue with his arguments against C++ exceptions. You can regard the C++ Exception as a “goto” with an unknown destination. This does sound like a recipe for a “bad smell” in your code. But C++ Exceptions are designed for handling errors that occur in a self contained part of code that can’t know what the correct way (because it depends on the time of usage) to behave when the error is encountered. By passing back an exception it allows the calling code to decide how to handle the error condition. This is an invaluable tool when used correctly. C++ Exceptions are great for solving this design challenge. But please don’t use them for anything else. Any other use immediately drifts into the problem area discussed by Joel Spolsky in his document.

The Software is Finished – Part 2

I have customers who ask “When will the software be finished?”. I have more experienced customers who ask “When will the software be ready to use?”. The previous posting was heading to the conclusion that software is very very rarely actually “finished”.

You need a bit of software. So it must be doing some kind of useful task. Parts of the software may very well be useful in the future (even as part of a solution to a completely different task).

It’s a failure for all concerned if software has to be consigned to the “Recycle Bin” because it has become “so tangled and uncontrolled that it is no longer maintainable or useful” . If you are investing your time (or your money to pay for someone elses time) you want your investment to be worth while. This is achieved by taking time out to plan how to avoid “case b)” and to design according to you plans.

So….

Do use Unit Tests.
Do think about how you are going to test the overall software operation (and document this).
Do refactor
Do use sensible function and variable names
Do keep your documentation up to date.

Never to a quick fix “because the software is basically finished”. Never think software is finished.

The Software is Finished – Part 1

I have customers who ask “When will the software be finished?”. I have more experienced customers who ask “When will the software be ready to use?”.

Having been writing software since the days of the Motorola M6800 (Motorola’s first microprocessor, programmed in assembly language) I have completed many contracts. As a business I have to also ask “When can we invoice for the software we have written?”. But I can’t think of many software projects that were genuinely “finished”.

Software seems to come to an end when either

a) The use for the system the software is running on disappears.
b) The development of the software has become so tangled and uncontrolled that it is no longer maintainable or useful.

If you take case a) this actually rarely means the software is “finished”. Even in those early 100% assembly code projects that I did later versions of Motorola microprocessors were assembly code compatible with earlier versions (most successful being the upgrade from the M6800 to the M6809 family). Even assembly language that is not of the same family can often be manually ported across to a different CPU if it was originally well written and well commented.

The key to good software is that it must be easy to re-use. You will find it very hard to stay in business if you try to write everything from scratch. If this goal can be achieved then case a) above becomes suprisingly rare. Trying to think of an example where an actual system disappears completely is hard. Perhaps, if the oil runs out and we can’t get any fuel for any internal combustion engine then all the engine management software out there might genuinely be “finished”…..

So that means that case b) is the most common reason for software being “finished”. Case b) must be avoidable in all cases (provided there is awareness of the need to avoid it).

More to follow in next posting.

A Forum for Embarcadero C++ Users ?

As mentioned on my posting of 16th Nov 2020, Embarcadero have shut down the invaluable forum that used to be at https://community.idera.com/

I’ve been alerted to the new branch on the Delphi-Praxis forum site that is devoted to Embarcadero C++ users. This has been set up in response to the Embarcadero closure.

You can reach this new forum by clicking on https://en.delphipraxis.net/forum/41-general-help/

Embarcadero RAD Studio and C++ Builder now Bundle TwineCompile

The clang C++ compilers are very powerful, offering full support for C++ 17. Anyone who has read Bjarne Stroustrup’s “A Tour of C++” (the second edition covers C++ 17) will realise that a compiler has a very large amount of things to do as it translates source code to object code. This comes at a price. Compiling RAD Studio or C++ Builder projects using the clang compiler for any reasonably sized project takes tens of seconds (tens of minutes for a complete build of a very large project).

Jomitech produce a RAD Studio plugin called TwineCompile that can very significantly shorten compile times.

TwineCompile

In August 2020 Embarcadero announced a bundling of TwineCompile for all customers using RAD Studio or C++ builder Enterprise or Architect with an up to date subscription package. For those who qualify this is now available under the Getit package manager in the IDE.

So if you are on Enterprise or Architect what are you waiting for ? Go “Getit” !

Code Review – Guidelines

I’ve taken on a new role for a software project based on Embarcadero Delphi code, that of Code Reviewer.

I’m a C++ programmer and have little experience with actually writing or debugging Delphi code.

So does that mean that I am the wrong man for the job?

Here are two things I won’t be doing:

I won’t be testing the code by running it (other people in the development team will be doing this alongside the original testing done by each other programmer as he/she develops the code).

I won’t be looking for syntax errors. The code should compile and run before it is passed to the code reviewer.

So what will I be doing?

I will be looking at the overall method used to perform the functions. Is it a sensible algorithm? Are looping structures sensibly implemented?
I will be looking at the choice of names used for variables, procedures and functions (there are plenty of blog postings about this here!).

I will be looking at comments, particularly any lengthy text that summarises the tasks achieved by the code to try to ensure that they are clear and simply written yet are accurate and complete and not open to misinterpretation. I will also check that they actually exist at the top of each source code file.

Whilst doing so I will be careful to be positive and respectful to my fellow team members. In particular for many, English (the language used for the code and comments) may not be the native language of some of the team members so any grammar / spelling or improvements to accuracy or coherency of explanation will be done in a sensitive manner.

That’s my aim.

If you consider these items you realise that in depth experience with Delphi is not a prerequisite to achieving the aims. In fact it may be argued that a lack of in depth expertise may even be useful!

Naming arguments and variables: Index and Number

It’s very common to have integers that are used to count objects. It’s also very common to have integers that are offsets into arrays (or similar structures).

Humans tend to count from 1 to n. In almost all cases when software uses offsets it makes sense to design the offset to run from 0 to n-1. Sometimes it is obvious which applies to a variable or function parameter. Sometimes this starts off being obvious but with the passage of time and the increase in the code complexity it becomes less obvious (even to the original code author). I know because I’ve been there.

There are also cases where it may not be so obvious from the start. Suppose you have a function which is passed the user response to the question “which one in this list of items do you want?”. Does the function return “1” if the user want’s the first one in the list or does it return zero?

I strongly encourage the use of the words “Index” in variable names which are expecting 0 to n-1 values and “Number” in variable names which are expecting 1 to n variables.

Thus you might declare the above function as

int GetUserSelectedNumber(void);

if the function returns 1 if the user selects the first item, or

int GetUserSelectedIndex(void);

if the function returns 0 if the user selects the first item.

Similarly if you have three things to control stored in an array, you might write:

const int NumberOfWidgets = 3;
TWidget Widgets[NumberOfWidgets];

and you could have a function somewhere that is declared as

void DoSomethingWithWidget(int WidgetIndex);

This is then immediately clear to everyone that the integer passed must run from 0 to n-1 (ie 0 to 3).

It’s a simple naming convention but it can save you hours when supporting your older (ongoing) code..

Stick with one Editor

To many this may be obvious. But it’s amazing how many people use the editor that comes with each of their IDEs with the confusion that arises as a consequence of each editor supporting different “advanced” features and/or short cut keys etc.

The Embarcadero IDE editor is a good one. Having got to learn it “inside out” I now use it for all major program writing. For example when working with Freescale microcontroller C code I use the Embarcadero editor for all code creation and only use the Freescale “Codewarrior” IDE editor for quick fixes whilst in the debugger.