Steve Yegge on Requirements

This is just sharing a link to Steve Yegge’s rant on business requirements.

I can’t really say any more than that. Anyone who knows Steve’s posts will know that he says everything possible (and more) on his subject of the month. (Those who don’t know Steve’s posts will want to get a coffee before they start.)

Disclaimer: Zooba’s Blog takes no responsibility for any offence caused by swearing, alternative ideas and liberals on external links. (Of course, if you like it, feel free to say that I sent you.)

Comments off

Windows Live Writer

All those bloggers out there, I can’t strongly recommend Windows Live Writer enough. It automatically supports WordPress blogs (ie. enter URL, username and password and you’re done) including saving local drafts, online drafts and publishing. It also supports uploading images either directly to the blog or to a separate FTP server.

(A spell check is provided, but a blogging tool that doesn’t recognise "bloggers" is slightly concerning.)

The web preview is really cool. If you allow WLW to post a temporary blog for you then it will download your style and give you a preview using it.

Devs will need either the Paste from Visual Studio plugin (for VS users) or you’ll (ByteClub bloggers) have to mess around with <code> tags (not fun, plus VS highlights better for supported languages). <code> tags don’t preview correctly, which is a shame but understandable. The other code formatting plugins I looked at supported next to no languages.

Paste from VS is nice though:

/// <summary>
/// Generates a sequence from <paramref name="start"/> to <paramref name="end"/>,
/// incrementing by <paramref name="step"/> each time.
/// </summary>
/// <param name="start">The first value to return in the sequence.</param>
/// <param name="end">The value after the last value to return in the sequence.</param>
/// <param name="step">The increment for each step. This value will have its sign adjusted
/// automatically to prevent infinite sequences.</param>
/// <returns>A sequence of integers from <paramref name="start"/> to
/// <paramref name="end"/>, not including <paramref name="end"/>.</returns>
/// <remarks>If <paramref name="start"/> is equal to <paramref name="end"/>, or
/// <paramref name="step"/> is equal to zero, a sequence containing one value
/// (<paramref name="start"/>) is returned.</remarks>
public static IEnumerable<int> To(this int start, int end, int step)
{
    step = Math.Abs(step);

    if (start < end && step > 0)
    {
        for (int value = start; value < end; value += step)
            yield return value;
    }
    else if (start > end && step > 0)
    {
        for (int value = start; value > end; value -= step)
            yield return value;
    }
    else
    {
        yield return start;
    }
}

 

And as a test of the image uploading, I’m reposting an image shared on Twitter by @andrewdotnich. The drop shadow is provided by WLW, as is the watermark. There is also resize functionality and other effects.

 Twins

There is also very nice integration with Virtual Earth, Microsoft’s answer to Google Maps, which allows me to spend about 30 seconds answering the question everyone wants to know… where is Swinburne?
Where is Swinburne?

The only problem I had was with the initial install. The installer downloadable from the Windows Live website (why is website not in WLW’s dictionary?) is actually a downloader that talks to Windows Update. Occasionally, Windows Update won’t talk back, so try again later.

Hopefully having a nicer writing environment will increase my blogging output. Or maybe not…

Comments

Three things that aren’t taught early enough #3: Multithreading

(Okay, okay. It’s been a long break, I know. I had exams, then I had an “unwinding-after-exams” period consisting of a week either in bed (sleeping) or at various jazz bars around Melbourne (not sleeping). But finally, the finale is here.)

To complete this series (previous posts being #1: Unicode and #2: Dynamic Link Libraries), I now bring you the third and final thing that isn’t taught early enough.

Thing Three: Multithreading

In September last year, Andrew Coathup posted the “Rules of Threading”:

  1. If you think you need multi-threading, you’re wrong
  2. If your specification says “you need threading”, see Rule 1
  3. (for advanced users only) If you think you need multi-threading, you’re *probably* wrong

(Attributed to a forum post(?) by Jon Kale, though I was unable to find the original.)

While I’m perfectly happy with rule 2, rules 1 and 3 need some clarification (which I intend to give, to the extent that I can assume the original intent behind the rules).

There are effectively two approaches to multithreading: algorithmic and task (note that I just made these up based on experience and widespread reading. Also, task multithreading is different to multitasking). The rules above apply to algorithmic multithreading, but not task multithreading.

To illustrate the difference, Jeff Atwood almost exclusively talks about algorithmic multithreading. The BackgroundWorker component in the .NET class library is designed for task multithreading.

In effect, algorithmic multithreading is dividing a single algorithm into multiple threads (”parallelising”), while task multithreading is spinning an entire algorithm into a separate thread so it does not block the main thread.

So to restate the rules above more explicitly:

  1. If you think you need algorithmic multi-threading, you’re wrong
  2. If your specification says “you need algorithmic threading”, see Rule 1
  3. (for advanced users only) If you think you need algorithmic multi-threading, you’re *probably* wrong

(Hopefully by now Mr. Kale is jumping up and down screaming “duh!” at me. If not then his rules are very broken.)

Algorithmic multithreading is hard. Very very hard. There are not many programmers who are happy to write this sort of code. There are even less who can make it work, and less again who can debug it when things go wrong. There are also very few algorithms that are sufficiently parallelisable to achieve large performance gains. A lot of wasted effort goes into very small performance gains.

Relative to algorithmic multithreading, task multithreading is simple (as is rocket science, but task multithreading is even simpler than that). With library support such as the BackgroundWorker component it falls into the realm of intermediate, event-driven programming. With basic synchronisation primitives it is probably just on the advanced side of things. Even so, it is absolutely fundamental to any modern application that interacts with a user.

Task multithreading is what allows you to use tab B in your browser while tab A is loading. Downloading and rendering requires a lot of waiting for remote servers and local processing (for example, JPEG decompression). A purely single-threaded application would lock up while this is going on. With a sufficiently fast internet connection and processor, the locking up may not be noticeable. In practise, the non-responsiveness would be readily apparent to a user, even on locally stored data.

To avoid this situation, the downloading process is run in a separate thread, allowing the browser to remain responsive while (apparently) simultaneously downloading another page. There is still a delay while the page loads, in fact the delay is probably longer than in the purely single-threaded case, but the apparent delay is much less.

Task multithreading is all about one rule. Never execute a long-running piece of code in the UI thread. The (.NET) example shown looks complicated, but comes down to two main points.

  1. Run extended tasks (longer than a few milliseconds) in a separate thread.
  2. Notify the UI thread when complete.

This is slightly different to the fork/wait model, in that no waiting is performed. It is more akin to the callback model, though again, not identical. (Callbacks usually operate on the thread doing the calling. We want to operate on a different thread.) The Invoke method performs this task in the Windows Forms world, while a custom window message is usually most appropriate for native Windows applications (and I don’t actually know how to go about doing this in *nix).

These tasks have a few common characteristics. The amount of locking required is normally pretty low and where it is required coarse-grained locking is generally appropriate (for example, preventing the user from modifying a document while we are saving it). The task needs to report progress somehow (even if it makes it slower, when the user sees a progress bar the process feels faster) and be able to be cancelled (both of which are as simple as shared variables). The implementation is not complex and doesn’t deserve to be lumped in with algorithmic multithreading.

So, how is teaching affected by this? Apparently the PSD course includes multithreading as a topic in one or two subjects, but it should go further than this. Issues such as race-conditions pop up everywhere and should be mentioned, if not solved, when they do.

As an example, the following code has been presented as the implementation of the singleton pattern:

class Singleton
{
protected:
    Singleton();
 
private:
    static Singleton* instance;
 
public:
    static Singleton* GetInstance()
    {
        if(instance == NULL) instance = new Singleton();
        return instance;
    }
};

Great! Simple, neat, easy to follow. Now, on the next slide, show the same example in a form that you’d actually write it in:

class Singleton
{
protected:
    Singleton();
 
private:
    static Singleton* instance;
    // Assuming a nice mutex wrapper class
    static Mutex instanceMutex;

public:
    static Singleton* GetInstance()
    {
        Singleton* returnValue;

        instanceMutex.Wait();
        if(instance == NULL) instance = new Singleton();
        returnValue = instance;
        instanceMutex.Release();
 
        return returnValue;
    }
};

The time between testing, modifying and returning a variable is not negligible. Without locking, there are three places where instance could be modified by another thread causing incorrect results (in this case, multiple instances of Singleton). (Note that this code still suffers from the destructor of Singleton never being called - very relevant if Singleton is actually a handle to an open log file.)

There is no more appropriate application for Murphy’s law than in multithreading. It only takes a little bit of defensive programming and discipline to prevent problems caused by task multithreading. This discipline needs to be taught, and demonstrated, wherever race-conditions crop up (ie. basically everywhere).

In terms of teaching algorithmic multithreading, I believe you’re looking at an entire subject. At least. Probably a post-graduate subject. Maybe there is one already? If so, great! If not, that’s excusable, to an extent. That extent being the pervasiveness of multithreading throughout all the applicable areas. Which is not very good. So it isn’t really excusable. In any case, having a single “threading” subject does not remove the need for safe programming tactics to be taught everywhere, just as teaching task multithreading does not remove the need for a specific algorithmic multithreading subject.

Looking at the layout of the PSD course, I would pick the second semester (of the first year) as the time to start introducing task multithreading and basic defensive techniques as shown above. It doesn’t have to be an entire subject. It doesn’t have to be specifically tested (though some of it probably should be). It just needs to pop up again and again and again. There is no excuse for anyone who is writing a singleton class to not make it safe for use in a multithreaded environment. There is no reason for students to be scared of the second example above, or have no clue what it means (after being taught, obviously). Code examples that come with “needs error checking” disclaimers also need a “needs multithreading protection” disclaimer as well.

No exceptions.

(No pun intended.)

Comments

Why delete[] is important: Answers

A somewhat disappointing lack of attempts at the exercises in my last post. I would hold out for longer but it’s doubtful that anyone will come across it now who hasn’t already. So here are the answers. (Read the original post if you haven’t yet.)

Exercise 1 (easy): Why shouldn’t you use the scalar delete operator on an array of an objects, even when you know there is no destructor?

Answer: Because code changes. If a destructor is added to that object, all your existing code will now break. Also because the rules are there to be followed. Don’t mix-and-match memory management functions.


Exercise 2 (hard): Why can’t the array delete operator determine how many objects have been allocated based on the amount of memory allocated for them?

Anwer: Under certain circumstances, it can.

Firstly, the underlying memory allocation routine has to provide some way of retrieving the size of an allocated block. For example, _msize() or HeapSize().

Secondly, the amount allocated has to be exactly the amount requested. Neither _msize() and HeapSize() give any indication that this isn’t the case, so all looks good.

Unfortunately not.

malloc() and HeapAlloc() contain the following sentences:

The malloc function allocates a memory block of at least size bytes.

If HeapAlloc succeeds, it allocates at least the amount of memory requested.

It makes a lot of sense to be able to allocate 4 bytes even though the caller requested 3. Maintaining the alignment of the next block is worth it.

The result of this is that array delete cannot rely on the allocated size accurately reflecting the number of objects. Extra information is required.

Comments

Why delete[] is important

A brief sidetrack from my “three things” series (or thing 2.5, if you like). I’m going to talk briefly about the array delete operator. The reason I want to bring this up is that it was incorrectly taught this semester just been, and while I don’t pretend that everyone who was taught the wrong thing will read this, at least I know I’ve done about all I can.

As everyone knows (if this doesn’t include you, I’m about to explain it anyway, but you should feel slightly less knowledgable about C++ as a result), C++ uses the new and delete operators (yes, they are operators) to allocate and free memory. They also handle (in a sense) calling object constructors and destructors.

class MyClass;
 
MyClass* myClass = new MyClass();
delete myClass;

To allocate/free more than one object at a time, the array new and array delete operators are used.

class MyClass;
 
MyClass* myClass = new MyClass[16];
delete[] myClass;

The general rule is do not mix and match the two types of operators. For example:

// Incorrect code coming up.
// Copy & paste at your own risk
MyClass* myClass1 = new MyClass[16];
delete myClass1;
 
MyClass* myClass2 = new MyClass();
delete[] myClass2;

The second example is less common. The first occurs much more often, and is an example of the incorrect teaching I mentioned earlier. When the array new operator is used, more than just x objects are allocated. Raymond Chen has a reasonably thorough explanation of how the Microsoft VC++ compiler handles this.

The main problem is that, once allocated, an array is indistinguishable from a single object. The compiler cannot (usually) display a compile or run-time error when the new and delete operators are mismatched. To make things worse, sometimes they can be mismatched and still work perfectly (this is one of the answer to Raymond’s bonus exercise).

In the case where memory is allocated with array new, most likely some metadata (the array size) has been stored at the start of the memory block and the pointer returned is not actually at the start. Using scalar delete on this memory will successfully call the first destructor, but will (probably) fail on freeing the memory since the pointer provided is not at the start of the block. It is even possible for the scalar operators to use a completely different allocator to the array operators.

For the case where scalar new and array delete are used, the delete operation will be looking for metadata that has not been included. So instead of the number of elements in the array it ends up with some random number. The destructor is called twenty million times (probably causing an access violation, but if not…) and the deallocation fails since we’re trying to point to memory before the start of the block.

What about the case where you can mix and it does work?

Unfortunately for the lecturer involved, the example given did work even though it was wrong. This is unfortunate because a crash or an error would have given him the opportunity to correct the mistake. As it was, the class saw that using scalar delete on a block allocated with array new works fine.

It doesn’t.

Well…

Sometimes it does.

(If the assembly language doesn’t give away what’s going on, the class names should.)

class TypeWithDestructor
{
    void* value;
public:
    TypeWithDestructor() { value = this; }
    ~TypeWithDestructor() { }
};
 
class TypeWithoutDestructor
{
    void* value;
public:
    TypeWithoutDestructor() { value = this; }
};
 
int main()
{
    TypeWithDestructor* myArray1 =
        new TypeWithDestructor[4];
    TypeWithoutDestructor* myArray2 =
        new TypeWithoutDestructor[4];
 
    delete[] myArray1;
    delete[] myArray2;
 
    return 0;
}

The assembly code has been cleaned up to make it more readable for non-assembly language programmers.

; 27   :     myArray1 = new TypeWithDestructor[4];
 
    push    20 (00000014h)
    call    operator new
    add     esp, 4
    mov     DWORD PTR [eax], 4

    push    OFFSET TypeWithDestructor::~TypeWithDestructor
    push    OFFSET TypeWithDestructor::TypeWithDestructor
    push    4
    push    4
    add     eax, 4
    push    eax
    call    `vector constructor iterator
    ; assume EAX is preserved
    mov     myArray1, eax
; 28   :     myArray2 = new TypeWithoutDestructor[4];
 
    push    16 (00000010h)
    call    operator new
    add     esp, 4

    push    OFFSET TypeWithoutDestructor::TypeWithoutDestructor
    push    4
    push    4
    push    eax
    call    `vector constructor iterator
    ; assume EAX is preserved
    mov     myArray2, eax
; 30   :     delete[] myArray1;
 
    mov     ecx, myArray1
    push    3       ; destruct (02h) and free (01h) memory
    call    TypeWithDestructor::`vector deleting destructor
; 31   :     delete[] myArray2;
 
    push    myArray2
    call    operator delete

For those who missed it, classes without destructors (okay okay… classes with an automatic, trivial destructor [nitpickers]) don’t use the vector delete operator.

Compare the last two examples. The first one passes the pointer (myArray1) to a “vector deleting destructor” function, belonging to the class. By comparison, the last example passes myArray2 on the stack directly to the scalar delete operation, which is usually the equivalent of a free() call.

Now compare the first two assembly language snippets. The first line in each pushes the size of the memory block onto the stack. Each object will be 4 bytes and there are 4 of them, so we expect 16 bytes. However, for TypeWithDestructor, 20 is being pushed. The reason for this can be seen just after the call returns where 4 is moved into the first 4-bytes of the memory. This is the array count. TypeWithoutDestructor does not need this count to be included. Destroying myArray2 is a simple matter of freeing the memory block. myArray1 on the other hand, requires the number of objects to be known so destructors may be called for each of them.

I’m tired of typing now, so I’ll leave two exercises and hopefully get some comments coming.

Exercise 1 (easy): Why shouldn’t you use the scalar delete operator on an array of an objects, even when you know there is no destructor?

Exercise 2 (hard): Why can’t the array delete operator determine how many objects have been allocated based on the amount of memory allocated for them?

Comments (2)

Three things that aren’t taught early enough #2: Dynamic Link Libraries

Continuing the series started with Three things that aren’t taught early enough #1: Unicode, I now present thing number two:

Thing Two: Dynamic Link Libraries

Modern operating systems live on dynamically linked libraries (abbreviated to DLLs from here on in, which refers to the general concept, rather than the Windows-specific implementation). Huge amounts of code is provided to applications (there’s over 800MB in my Windows Vista system32 folder) which simply cannot be included directly into any compiled application. Unfortunately, the most a second or third year (or later?) computer science student could tell you about is DLL hell, and they probably won’t get any further than the name.

DLLs are (still) the top step in increasing levels of physical code-separation. Early (very early) programs consisted of a single monolithic source file. (Even earlier ones consisted of a single monolithic punch card…) This gave way to separate files which were compiled separately and then linked (called “object files”, commonly COFF and ELF). Commonly used object files started being collected/archived into static libraries, allowing much greater code reuse than OOP has ever achieved. The big disadvantage of static libraries is all the code gets included into the executable. When 100 applications include the same 1MB of code, that’s 99MB worth of duplication.

Enter DLLs. When an executable starts, the loader determines whether the required DLLs are in memory or not. If they are, the loaded code is used. Otherwise, the DLL is found and loaded from disk. All advances on DLLs have mostly been aimed at reducing dependency issues, including through side-by-side installation of multiple versions (something that has been in *nix forever (or close enough)), tighter interface conventions (for example, ActiveX/COM) and stronger naming conventions (as in .NET assemblies).

<Windows Specific>
(The implementation of DLLs is operating system specific. I don’t have any inside knowledge of *nix style .so files (though I know that they are identical to MacOS .dylib files), so I will only discuss Windows .dll files. Presumably the concepts are applicable to all DLLs, otherwise they would be implementing different things.)

A .dll file is fundamentally identical to a .exe file. In fact, they are completely identical in implementation. An .exe file can be used as a DLL if so desired. All Portable Executable (PE) files include import and export tables. The export table contains a list of function names and addresses which may be called from outside the file. No information on calling conventions or parameters is included as this is meant to be shared separately. Name mangling is used in various forms to better enforce function signatures, though it usually doesn’t include enough information to make shared header files unnecessary. Unfortunately, different compilers perform different name mangling, making DLLs hard to share. For this reason, extern “C” is generally recommended, as this disables name mangling (as well as parameter overloading).

DLLs are used by another program in one of two ways. They are either dynamically loaded, using functions such as LoadLibrary() and GetProcAddress(), or automatically linked. Automatic linking is performed by the loader using the contents of the import table. Information is included in the application about functions that exist in another DLL, generally by use of a small static library. When starting the program, the loader will resolve these references, loading any required DLLs, and fix up function calls to point to the right memory location. If a function or library cannot be resolved, the program will not start. An advantage of dynamically loading a library is that the application can better handle a DLL error.

Dynamic loading also allows for better backwards compatibility. Newer versions of Windows provide API functions that didn’t exist in previous versions. If the loader is asked to resolve one of these functions and it cannot be found, the application will not start. If, however, the function is not essential, it can be dynamically resolved and called if available.
</Windows Specific>

So, what hasn’t been taught about DLLs? I would argue that the bare minimum is missing. The concept of a compiled software project that doesn’t actually run. The concept of exported functions and data (and also the concept of a linker). The issues arising from mismatched interfaces. A brief overview of name mangling and the issues that occur when mixing compilers. Exporting definitions for C++ applications (Microsoft’s dllimport and dllexport specifiers and gcc’s switches and conventions) (the trend is so strongly away from native applications that few other languages offer the ability to make native DLLs). Introduce and play with Dependency Walker and/or a *nix equivalent.

Issues such as redirection, forwarding, specifics about export tables, deployment and registration don’t need to be touched.

DLLs don’t require a huge amount of time dedicated to them, but no time is simply not good enough. Arguably they are not relevant in a pure computer science degree, but since nobody is teaching a pure computer science degree anymore DLLs should definitely get a showing. Along with Jeff Atwood, I also include version control in this sort of category. It needs to be taught, however briefly, before people get a piece of paper saying they can do stuff.

(Now I’ve mentioned version control it should be a big hint that it isn’t thing number 3. Number 3 is a huge one though, might be a couple of weeks off depending how much time I get. It will also include code samples a-plenty. Apologies for the delay, but hopefully it will be worth it.)

Comments (7)

Three things that aren’t taught early enough #1: Unicode

Before we continue, I’ll clarify the title slightly. I’m only talking about programming things and by “early enough” I mean they hadn’t been taught in the first two years of the CS&SE degree I’m doing. The concepts also only really apply to C and C++, though since C and C++ are still the most commonly used programming languages (combined) AND a full understanding of higher level languages can only be obtained through understanding the lower levels, I believe these points are relevant.

(If you disagree, post a comment and we can discuss it. That’s the point of comments. Better yet, write your own blog post and attract readers to yourself. Certainly many of the ByteClub blogs are way too quiet.)

I will post one thing per blog post. Partially through wanting to keep individual discussions on track and also through not wanting to have to write all three before I click “Publish”.

Thing One: Unicode

If I didn’t take an interest in programming outside of university, I would never have heard of Unicode. Blissful ignorance is a great excuse for “beginning” programmers, but the reality is not actually all that complex.

A bit of background. The first major character set (which maps numbers to displayable characters) was 7-bit ASCII (ASCII being the title, 7-bit being relevant information). Hopefully everyone has just worked out that 7-bits equals 128 possible characters. If you consider the English language (which, not surprisingly, the American Standards Association (later ANSI) did) the characters that need to be displayed are upper and lowercase letters A through Z, each digit, and a sprinkling of punctuation. This fits quite well into 7-bits, including some leftovers for control characters.

But then, people in countries where other languages are spoken decided that they deserved to be able to use their own language’s characters. So they started using codes 128-255. Except, these codes were being used in different ways in different places. Greek characters bear little resemblance to French characters, so Greek computers would use a different set of characters in the 128-255 range. Computers would ship with a selection of so-called “code pages“, allowing the user to select their preferred character set.

Now, when sending email from Greece to France (because people sent lots of emails prior to 1991), the code page had to be specified to ensure your ωs weren’t changed into çs. Of course, this whole setup failed miserably. So Unicode was developed.

Rather than assigning each character a single value between 0 and 255, Unicode assigns each character a code-point value. (One of) a variety of encoding schemes are then used to store this code-point, the two most popular being UTF-8 and UTF-16. UTF-8 is based around byte-sized (8-bit) elements, while UTF-16 is based around word-sized (16-bit) elements - to use the C++ data types, char and wchar_t (or unsigned short).

The majority of code-points fit into 16 bits (ie. are less than 0xFFFF), making UTF-16 efficient for when a wide variety of languages (or even only one, providing it’s not English) will be used. The majority of code-points for the English language fit into 8 bits (ie. are less than 0xFF), making UTF-8 more efficient for files consisting primarily of Latin characters. UTF-8 also has the advantange of being able to decode ASCII encoded files, which is why it is the most commonly used encoding.

However, there is a catch. A program that supports UTF-8 can read ASCII files, but not necessarily the other way around. The reason for this is that ASCII is a single-byte character set (SBCS) while UTF-8 is a multi-byte character set (MBCS). Basically, ASCII guarantees that 8 bits is enough to describe every supportable character. UTF-8 guarantees nothing. If a character cannot be encoded into 8-bits (technically 7 bits), it will be split across two bytes. Or three. Or four. Or five. Or six! Suddenly everything taught about ASCII strings goes out the window.

Consider the following code:

char* myString
 
int count = 0;
for(char* c = myString; *c != \0′; ++c)
{
    count++;
}

Now, what does this snippet do? Think about it.

The obvious answer is that it counts the number of characters in the string. This is incorrect. It actually counts the number of bytes used by the string. The difference may not be obvious if you attended the same classes as I did. The char data type is a signed, 8-bit integer - one byte. Each increment counts as one, regardless of the contents of that byte, provided that it isn’t the null terminator.

For a SBCS, like ASCII, each character requires one byte, so the number of bytes will always equal the number of characters. For a MBCS, like UTF-8 (and UTF-16), a single character may be encoded in more than one byte. For an English string this is unlikely. However, throw in some accented characters and counting bytes is an incredibly inaccurate way of counting characters (though it is still relevant in terms of dealing with the encoded string, just not in decoding it back into individual characters).

The work-around? It’s relatively simple, though potentially not nicely portable. Microsoft’s Visual C++ library has macros for traversing a string, and the UTF8-CPP library looks quite similar, though neither are built into the language (no “batteries included”). Operating systems provide suitable functionality and support for character processing, and apparently current C and C++ standard libraries have MBCS support (I am somewhat doubtful with regards to the std::string class).

UTF-16 suffers from the same issue, though not to the same extent. UTF-16 is predominantly used on Windows systems and is the standard for that platform. Most, but not all API calls support using either UTF-8 or UTF-16 (incorrectly referred to as ANSI and Unicode, and providing the current code-page is set to UTF-8) though some more recent functions only support UTF-16. *nix based operating systems usually use UTF-8 and “wide characters” are actually 32-bits, making direct compatibility difficult.

So how should this be taught? A good start is actually Java, C# or VB, since the char data type in these languages represents an entire character, rather than an 8-bit integer. When C++ starts to be used for processing strings, the wchar_t type is a much better option. *nix compilers will treat this as a 32-bit integer, capable of encoding every known character, while Windows will treat it as a 16-bit integer, capable of encoding most. (The char type should only ever be used for strings in cases where memory is more important than processing speed, ie. never.) The standard C++ library provides wide versions of the iostream streams such as wcout and wcin, as well as wstring and wstringstream classes which, while probably not perfect, are considerably better than the 8-bit alternatives.

Finally, teach operating system specific function calls. There is going to be more than one subject where this comes up, so do one on Windows and one on Linux. Specifically, teach documentation reading, how to find functions in MSDN and whatever-the-Linux-equivalent-to-MSDN-is. Most graduates are going to end up programming for Windows anyway, probably in a language where OS specific calls are impossible. Ideologically teaching everything in an OS that doesn’t cost anything is of no help to students. Teaching a full range of content is.

To summarise (for all those tl;dr people), ASCII is dead and has been for a long long time. To still be teaching that one-char always equals one-character is inexcusable and is not setting up the next generation of developers to be able to handle a global audience. Higher level languages provide better support built-in, but an understanding of character sets and code pages is as essential to being a well-rounded software developer as is bits and bytes (ie. very essential, but that’s a different topic (no, not in this series)).

For futher reading, I recommend Joel Spolsky’s “The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)”.

Comments (3)

stackoverflow.com

For those who don’t read around as much, stackoverflow.com is the brainchild of Jeff Atwood and Joel Spolsky. At the moment there are only two podcasts and a clever cartoon to show for it, but the general idea has been explained.

(A short summary follows. Alternatively you can read Jeff’s announcement, Joel’s announcement or get the podcasts (RSS). Following the summary is my take on the whole thing.)

In short, stackoverflow.com is a cross between Wikipedia and Reddit and a discussion board. Developers/programmers/geeks/people ask questions which are answered in a collaborative form. Responses can be voted up or down to increase your “karma”, which increases your ability to post on more important topics. The aim is to achieve the top Google result for each topic, much like Wikipedia has the top for everything.

(End summary)

Obviously the idea hasn’t been fully developed, or if it has, it hasn’t been expressed clearly. It could be nothing more than a generic discussion board, or it could be a thriving community developing a collection of code snippets. There are some obvious inconsistencies in my summary above, but that is Jeff and Joel’s fault, as far as I’m concerned.

In my opinion, a collaborative code-snippet collection would be great. A Yahoo! Answers site would be pointless. Unfortunately, based on the questions and answers in the second podcast, the latter appears to be more likely.

Specifically, the question was asked whether code would be given in multiple languages, with filtering available similar to the MSDN Library. The answer was along the lines of “it depends on the wording of the question.” A question like “how can I use VB to send an email” gets a different answer to “how can I send emails in any language.”

But the relevant part is sending email. Why does it matter what language they ask about? Why have one answer that gets voted as the ‘best’? Why not have a page titled “Sending email”? Sections of the page can be tagged with the language to allow for filtering. The sections can also be tagged with complete/incomplete and a BugMeNot style vote can be used to indicate whether the snippet worked. “Karma” can be awarded based on a person’s contributions and votes. (This is also similar to the model used at a number of song lyric sites.)

Encouraging questions encourages a few bad habits. Homework questions tend to be quite an issue. “Dorothy Dixer’s” that lead to advertising of a particular library or language are equally to be avoided. To some extent, both of these are avoided under the Wikipedia model. Homework questions don’t appear when the emphasis is on contributing, rather than asking. Blatant advertising can be easily removed by any contributor.

The idea still needs clarification. With the star-power of Spolsky and Atwood behind it the site is sure to start strongly, the difficulty will be in building a culture that works. I don’t read Joel’s discussion board or the comments on Jeff’s blog posts because the amount of noise is so high. If this carries over to stackoverflow.com, the highly skilled programmers simply will not hang around.

Jeff, Joel: you have a chance to do something great. Don’t waste it.

(Also, on the “should all programmers learn C” issue, I disagree. C is much too high-level for the proposed benefits. Everyone should learn assembly language, at least enough to implement the basic set of algorithms (search, sort, recursion, etc).)

Comments

The Benefit of Private Inheritance

(Yes the title is accurate. As you will see by the end of this piece, there is exactly one benefit of private inheritance.)

One of the (few) useful aspects unique to OO is inheritance. In general, inheritance allows you to expand an existing class to change or increase it’s functionality. Inheritance as known by Java and .NET programmers (and beginning C++ programmers) simply pulls down all the functions from a single base/super class and exposes them from your derived/sub class.

In the C++ world, though, inheritance is more complicated. The contents of more than one class may be used to construct a new class, and the accessibility of the imported members may be modified. The ’standard’ inheritance is known in C++ as public inheritance. All imported members have the same accessibility as they did in the base class.

class MyBaseClass
{
public:
    void doSomething();
protected:
    int aNumber;
};
 
class MyDerivedClass : public MyBaseClass
{
public:
    int getTheNumber() { return aNumber; }
};

Could have been written as follows:

class MyDerivedClass
{
public:
    void doSomething();
    int getTheNumber() { return aNumber; }
protected:
    int aNumber;
};

Private inheritance limits the accessibility of the imported members allowing only the immediate derived class access.

class MyBaseClass
{
public:
    void doSomething();
protected:
    int aNumber;
};
 
class MyDerivedClass : private MyBaseClass
{
public:
    int getTheNumber() { return aNumber; }
};

Is effectively the same as:

class MyDerivedClass
{
public:
    int getTheNumber() { return aNumber; }
private:
    void doSomething();
    int aNumber;
};

Protected inheritance exists but is basically never used. The same can be said for private inheritance, since it provides very little benefit over a second option. The example of private inheritance directly above could also have been written like this:

class MyDerivedClass2
{
private:
    MyBaseClass myClass;
public:
    int getTheNumber() { return myClass.aNumber; }
};

These snippets are actually examples of the Adapter pattern.

An adapter allows classes to work together … by wrapping its own interface around that of an already existing class.

To be more specific, the example using inheritance is an example of a class adapter, while the second is an example of an object adapter. Private inheritance is preferred for class adapters, since clients are prevented from modifying the underlying data structure. Programming languages that don’t support private inheritance must use an object adapter to achieve this.

So private inheritance may be used to allow the class you are writing to use a particular object without allowing the client or subclasses to also use it. Obviously (hopefully), this provides absolutely no benefit over simply declaring a private instance variable.

In fact, private inheritance is at a distinct disadvantage to an instance variable. How many other programmers will notice and understand the ‘private’ specification? Composing two concrete or partially implemented classes becomes mind-bendingly confusing and the risk of namespace collisions should turn even the most masochistic developer off private inheritance.

So what’s left? “Performance,” somebody yells. “Accessing a function attached to a member variable requires an extra lookup over accessing a function on the caller.” This is correct, under certain conditions.

Firstly, the function being called must have been marked virtual. A non-virtual function doesn’t appear in the virtual function table (duh) but is called directly.

Secondly, the instance variable must be a pointer to an instance, rather than the instance itself. Why? Because an actual instance must be a fully defined class. The following snippet shows both a valid and invalid example.

class LaunchableOutOfACannon
{
public:
    virtual void launch() = 0;
};
 
class PussyCat : public LaunchableOutOfACannon
{
public:
    void launch() { cout << “Meowwwwwwww!”; }
};
 
// A valid example
class MyObjectAdapterThatWorks
{
private:
    PussyCat obj;
public:
    void fireMe() { obj.launch(); }
};
 
// An invalid example
class MyObjectAdapterThatDoesntWork
{
private:
    LaunchableOutOfACannon obj;
public:
    void fireMe() { obj.launch(); }
};

Spot the difference? An abstract class cannot be instantiated, and so the type of an object that is specified in this manner (that is, not a pointer) must be fully known at compile time. As a result, the exact function call is known at compile time and a virtual function table lookup is not necessary. The other side of the same coin is that if a virtual function table lookup is required for the object adapter, it will also be required for the class adapter.

class MyClassAdapter
 : private PussyCat
{
public:
    void fireMe()
    {
        launch();
    }
};
class MyObjectAdapter
{
private:
    PussyCat obj;
public:
    void fireMe()
    {
        obj.launch();
    }
};
; void fireMe() { launch(); }
 
  mov  eax, [ecx]
  mov  edx, [eax]
  jmp  edx
; void fireMe(); { obj.launch(); }
 
  mov  eax, [ecx]
  mov  edx, [eax]
  jmp  edx

The optimised VC++ 9.0 output is identical for both the object adapter and the class adapter (as is the unoptimised output, but the optimised one is considerably neater). The virtual function table lookup occurs in both cases with the final function pointer ending up in edx. (Removing the pure virtual function from LaunchableOutOfACannon results in direct jumps to the function, as expected. Apparently VC++ 9.0 will not optimise out virtual function lookups.)

So private inheritance doesn’t have the benefit of speed or code size over a private instance variable. It doesn’t have the benefit of readability and can require incredible feats of mental gymnastics to follow code using it. The one and only advantage of private inheritance is that Java developers don’t get to use it. Nya nya nya nya nya nya! :P

Comments (1)

Quick Syntactic Sugar

VB has long held the reputation of making things easier for the developer at the cost of a syntax that can be understood by mere mortals. However, I have just discovered how much further this has gone…

From MSDN’s LINQ to XML Overview:

Creating XML Trees
The ease with which you can create XML trees is particularly significant. For example, to create a small XML tree, you can write C# code as follows:

C#

XElement contacts =
    new XElement(“Contacts”,
        new XElement(“Contact”,
            new XElement(“Name”, “Patrick Hines”),
            new XElement(“Phone”, “206-555-0144″,
                new XAttribute(“Type”, “Home”)),
            new XElement(“phone”, “425-555-0145″,
                new XAttribute(“Type”, “Work”)),
            new XElement(“Address”,
                new XElement(“Street1″, “123 Main St”),
                new XElement(“City”, “Mercer Island”),
                new XElement(“State”, “WA”),
                new XElement(“Postal”, “68042″)
            )
        )
    );

In Visual Basic, the code to construct the XML tree is even simpler, because it uses an XML literal:

Visual Basic

Dim contacts = _
    <Contacts>
        <Contact>
            <Name>Patrick Hines</Name>
            <Phone Type=“Home”>206-555-0144</Phone>
            <Phone Type=“Work”>425-555-0145</Phone>
            <Address>
                <Street1>123 Main St</Street1>
                <City>Mercer Island</City>
                <State>WA</State>
                <Postal>68042</Postal>
            </Address>
        </Contact>
    </Contacts>

The Visual Basic compiler translates XML literals into method calls into LINQ to XML.

Re-read that last bit. The Visual Basic compiler translates XML literals into method calls.

That is really really cool!

I doubt I’ll ever use it, since I’ve practically switched completed to C# (which has nice enough XML generation), but I can’t get over how cool that is! You just write XML right there, in-line with your code, and it parses it.

Wow…

Comments (1)

« Previous entries ·