Category Archives: Code

C++: Pointers to member functions

Now, C++ programmers can all program C, to varying degrees of competency. And some know that in C you can store an entire function in a pointer, like so:

int DoTheThingThisWay(double count)
{
...
}

int DoTheThingThatWay(double count)
{
...
}

int (*DoTheThing)( double );  // define the variable
DoTheThing = &DoTheThingThatWay; // set the variable
result = DoTheThing( 2.0 );  // call the function, whatever it is now

Giving you a nifty kinda polymorphism. People who have programmed in C, and needed something like this (say for a state machine) have gone “neat!” and remembered it for later.

So, here we are, later. I’m working in C++ and going to do a state machine. Objects and all. I recall that you can do that polymorphic thing with function pointers, and quickly reconstruct the syntax. Now, with objects I want to point at a function on an object rather than a dumb, lying around knowing nothing about objects function. Easy, let’s just whip that up, I’ve proven how pretty the syntax for calling an arbitary function is, now just to call an arbitary member function.

Half an hour of wrestling with the compiler later, an observation is made along the lines of “everyone does this, just look it up on the web”. Top hit on a Google search for C++ “member function” pointer is http://www.goingware.com/tips/member-pointers.html – which is the right page, and you end up with the call:

result = (objectInstance.*DoTheThing)( 2.0 );

which ain’t so pretty. But you need to do that to provide the hidden this pointer, because you’re working with member functions here, not boring old functions. Add some parameters, store the pointers in an array and before you know it you’ve got

result = (objectInstance.*DoTheThing[FunctionIndex])( 2.0, InitalStringSize, HuffalumpFactor );

which is a long way from DoTheThing(2.0), and I’m not sure what you just got for all that effort. Certainly not readability. Try a pointer to a polymorphic type instead (maybe even a functiod?), and flip the pointer to different objects as you go. Much nicer:

class CThingDoer
{
public:
	virtual int operator(double count);
...
};

class CDoTheThingThisWay : public CThingDoer
{
public:
	virtual int operator(double count);
...
} DoTheThingThisWay

class CDoTheThingThatWay : public CThingDoer
{
public:
	virtual int operator(double count);
...
} DoTheThingThatWay

CThingDoer* DoTheThing;  // define the variable
DoTheThing = &DoTheThingThatWay; // set the variable
result = DoTheThing( 2.0 );  // call the function, whatever it is now

Documenting Oracle databases

We all know what a right PITA it is keeping database documentation up to date. You’ll get a column added to the schema, and make a mental note to update the docs with the intricacies of how it works, then you’ll get distracted by something, never get around to it, then six months later you’ll be trying to remember the details.

Fortunately, the newer versions of Oracle have a rather marvellous commenting feature for tables and columns, so you can document it at the same time as you build it.

To put a comment on a table:

COMMENT ON TABLE xyz IS ‘This is a table for recording xyz usage’

Or on a column

COMMENT ON COLUMN xyz.frequency IS ‘Frequency of xyz usage’

Now, this might be of limited use if you couldn’t get the information out easily. Fortunately, you can. Apart from turning on the comments options in schema browsers such as TOAD, you can get a list of table names with their comments like this:

SELECT t.table_name, t.comments
FROM all_tab_comments t
WHERE t.owner = ‘tableowner’
AND t.comments IS NOT NULL
ORDER BY t.table_name

…and the following will generate a nice list of tables, columns, column types and their comments:

SELECT c.table_name, c.column_name, ac.data_type, ac.data_length, ac.nullable, c.comments
FROM all_col_comments c, all_tab_columns ac
WHERE c.owner = ‘tableowner’ and c.column_name = ac.column_name and c.table_name = ac.table_name
ORDER BY c.table_name, ac.column_id

Mind you, the data length field comes out a bit funny for CLOBs and Numbers. Still, with a little imagination you can write up a quick program to format this output nicely in HTML or WikiText or whatever, for your database documentation.

Monday snippets

From the forthcoming book The Search: How Google and Its Rivals Rewrote the Rules of Business and Transformed Our Culture, here’s an article about how Google got started.

How to deploy Visual Studio .Net applications to Linux. (via Brad)

Now maybe I can sell off my old BBC B, once I get a Beeb emulator working. Shame I might never recover my old Ultima clone that some friends and I were working on in 1988.

Cleaning up HTML out of Office

I found a good guide to cleaning out the gunk that’s in Word’s HTML documents. For the smallest most efficient files it seems to conclude that the Textism Wordcleaner — free for files under 20Kb; for bigger files subscription options are available. This issue has been causing me some angst for some time, and one of these days I’m going to bash out a tool for this myself. (Don’t hold your breath.)

A buncha stuff

I don’t normally link to the excellent DailyWTF, because it’s full of good stuff, I’d be linking every day. But yesterday’s picture of the server room with a fishbowl to catch the airconditioner water outlet is an absolute classic. (Make sure you read the article as well as look at the picture.)

Classical music labels have criticised the BBC for offering Beethoven’s symphonies as a free download. This strikes me as a tad narrowminded. I’d imagine there’d be a number of people out there who might otherwise not be interested in classical music who might listen to these then go out looking for more to buy. (via Dave Winer)

Microsoft are now offering free evaluation sessions in their products, making use of their Virtual PC technology so you just try things out on a remote session via your browser and Citrix Java client.

New version of Firefox (1.0.5) is available, fixing some vulnerabilities.

Regsvr32 goes wild

Task manager displayI was getting very odd results from Regsvr32 (the program for registering COM objects in Windows): it wasn’t doing anything other than creating a lot of processes which burned CPU for about 30 seconds before dying.

At first I thought it was the DLL I was trying to register. But even running the command with no argument produced the same result.

It turns out some errant install had replaced my pristine Windows XP SP1 copy of regsvr (version 5.1.2600.0) with some old copy (version 4.00.1381, which sounds suspiciously like it is from Windows NT 4).

Having found a colleague’s pristine copy, all was well again.

Mind you, XP complained shortly afterwards that some vital system files had been replaced, and asked for me to insert the XP CD. Do you think it would tell me which files had been replaced? Nope. Even the More Information button on the warning merely elaborated on the fact that the wrong CD was in the drive. Yeah, very useful.

MSDN fun

A couple of rather silly-sounding entries from MSDN…

Visual Basic: Class ContainedControls

Member of VBRUN – A collection that allows access to the controls contained within the control that were added to the control by the developer who uses the control. — What?

Win32 API: DeleteFile (via Josh)

Windows 95: The DeleteFile function deletes a file even if it is open for normal I/O or as a memory-mapped file. To prevent loss of data, close files before attempting to delete them. — uh huh.

Queries in OLEDB: keep your parameters in order

If like me you earn your keep writing code to interrogate databases, you’re probably familiar with parameterised queries. If not, take a look here — they offer a way of passing parameters into queries without all that mucking about with formatting for different data types and so on. They also offer (so I’m led to believe) performance gains from the database server. And OLEDB makes it pretty easy to do it, too. So throw away those horrible old queries and switch to parameter queries today!

One thing not often mentioned however is that the parameters have to be in order. Because in the SQL you identify them only as question marks:

SELECT FIELD1 FROM TABLENAME WHERE CRITERIA1 = ? AND CRITERIA2 = ?

they have to be added in the correct order. If you add CRITERIA2 then CRITERIA1 to your parameters, then you’ll get unexpected results. The parameter names don’t actually match up to your SQL by name, only by position. This is kinda logical, because if you wanted:

SELECT FIELD1 FROM TABLENAME WHERE CRITERIA1 > ? AND CRITERIA1 < ?

both your parameters couldn’t be named CRITERIA1.

For some of my code, I build an INSERT or an UPDATE depending on whether I have a new or updated record to write. To avoid two sets of code, I’ll build the parameter list with the key field last, and though it may seem counter-intuitive, I build the INSERT statement to match. Bad semi-VB pseudocode follows:

If (new record) Then
  SQL = "INSERT INTO TABLENAME (FIELD1, FIELD2, KEYFIELD) VALUES (?, ?, ?)"
Else (updating record)
  SQL = "UPDATE TABLENAME SET FIELD1 = ?, FIELD2 = ? WHERE KEYFIELD = ?"
End If

…then add my parameters FIELD1, FIELD2 and KEYFIELD in that order. Easy.

Microsoft 2005 dev tool betas

To those who watch Microsoft’s dev tools, there are betas of the 2005 versions now available. MSDN subscribers can download full products straight away; others can order CDs, or stick to the Express products, which for trying out new languages, are quite nicely featured.

It’s a cunning strategy for Microsoft, helping to counter the proliferation of free programming languages such as Java and PHP by providing free development environments for ASP, VB, C#, C++ and their own (some would say mutated) J# implementation of Java.

MSDE, which has been around for years now, providing a royalty-free cut-down SQL Server, has been renamed SQL Server Express to show its heritage. (Well, its SQL Server heritage… most people know it grew out of Sybase, but that’s ancient history). Keeping it free thus helps fight off the MySql threat and allowing people for whom Access isn’t cutting it to be encouraged up to SQL Server).

Looking back 20 years to when I was growing up, trying out BASIC on my Commodore 64 or BBC Micro, I ponder how the next generation of programmers are getting hooked into this game. I suspect a mix of freebie entry-level products like this (and their counterparts from the world of open-source) is one way they can get involved. Which probably explains MS’s “Coding 4 Fun” web site.

Classic VB go bye bye

Mainstream support for Visual Basic 6 (the last version before .Net) finished at the end of March, and there’s growing murmurs in the VB development community, calling for it to be resurrected. While “classic” VBers didn’t mind being shunted into the .Net framework, they objected to some of the bigger changes to the language itself, which made it difficult to migrate old projects over. And remembering that “classic” VB is the most popular computer language ever, there’s a lot of old systems out there still running with it. A petition has been organised, with nearly 200 MVPs having signed up so far.

Microsoft have put up a new site highlighting VB6 called VBRun (harking back to the pre version 5 days when the main DLL was called VBRun). It’ll have VB6 content on it, as well as nudging developers towards .Net.

I work with VB. I’ve got a lot of VB6 code still running. But I’m slowly moving some stuff over to .Net. I’m not convinced it’s better yet. It’s certainly different, but I’ll get used to it eventually.

How much should you customise?

Joel Spolsky has started a series on the making of FogBugz 4.0, initially talking about the requests of customers, and how (and when) this should translate into changes in your software.

The request for customisation is a question most of us involved in coding will face at some time or another. Even if your system has only a single “client”, do you really want to bend it and stretch it in such a way that it’s no longer future-proof?

In most cases, if you can avoid it, I suspect the answer is no. You want to keep it generic. Because as sure as night follows day, the pendulum of your customer’s direction will swing back the other way, and you’ll end up having to build yourself out of that hole they urged you to dig.

For example, in my work on the earlier version of what has become eVision’s Message Exchange, at times we have needed to generate and transmit messages quite different from the established standard types we were already spitting out. Natively we could handle XML and flat file (delimited or fixed-length) output files, but what if we wanted to add Zip compression on top of that? Or what about some other weird and wonderful thing?

In the case of Zip, we built that into the software using the very handy InfoZip DLL. But for others that appeared to be so specialised that we didn’t want to lumber the code with them forever more, we built on a “post-process” step, which allowed the output file to be subject to an external process before it was transmitted.

This kind of generic hook into the software has opened up numerous possibilities. So when the business dudes came along and asked for a file to be generated that did an additional lookup off a reference table, we were able to write that step as a separate process. It all works rather well.

So in some cases, the answer to customisation is interopability. Rather than bend and stretch your masterpiece into something it shouldn’t be, you put the hooks in so you or somebody else can do the bending and stretching over in a separate corner.

Your code can stay clean and future-proof, and everybody’s happy.