http://www.makepovertyhistory.org

The strangest of switch statements

Posted in Development on January 1st, 2010

When compiled as C this is a perfectly valid piece of code, yet you would have to be a few sandwiches short of a pick nick basket to write it (or an evil genius).

#include "stdio.h"
int is_even(unsigned char c)
{
        return c & 0x01 ? 0: 1;
}

int main()
{
        unsigned char c =4;
        switch(c)
        {
                default:
                        if(is_even(c))
                case 2: case 4: case 6: case 8: case 10:
                                printf("is even\n");
                        else
                case 1: case 3: case 5: case 7: case 9:
                                printf("is not even\n");
        }
        return 0;
}

String Calculator Kata

Posted in C++, Development, TDD on December 30th, 2009

Roy Osherove’s string calculator kata has been implemented in a number of languages, after trying it a couple of days ago and liking it I created a screen cast of my attempt. Incidentally if you want to view it is maybe best to view in high definition on vimeo.

I have added a download which includes the build script, two source files and the Xcode language specification file, more details of where to place the specification file is available on developer.apple. Something I noticed about watching the screen cast back is Xcode’s code completion for SC++L is really poor, IIRC the only suggestion in the whole the kata is for stringstream’s method “tellg”. It would be interesting to see how much more productive I am using an IDE I have used for years such as Visual Studio.

Finally if anybody has any comments either positive or negative then please do feel free.

  1. Create a simple String calculator with a method int Add(string numbers)
    1. The method can take 0, 1 or 2 numbers, and will return their sum (for an empty string it will return 0)
      for example “” or “1” or “1,2”
    2. Start with the simplest test case of an empty string and move to 1 and two numbers
    3. Remember to solve things as simply as possible so that you force yourself to write tests you did not think about
    4. Remember to refactor after each passing test
  2. Allow the Add method to handle an unknown amount of numbers
  3. Allow the Add method to handle new lines between numbers (instead of commas).
    1. the following input is ok:  “1\n2,3”  (will equal 6)
    2. the following input is NOT ok:  “1,\n”
    3. Make sure you only test for correct inputs. there is no need to test for invalid inputs for these katas
  4. Allow the Add method to handle a different delimiter:
    1. to change a delimiter, the beginning of the string will contain a separate line that looks like this:
      “//[delimiter]\n[numbers…]” for example “//;\n1;2” should return three where the default delimiter is ‘;’
    2. the first line is optional. all existing scenarios should still be supported
  5. Calling Add with a negative number will throw an exception “negatives not allowed” - and the negative that was passed.

std::fstream

Posted in C++, Development on May 7th, 2009
Hmmm
std::fstream f("filename",std::ios_base::binary | std::ios_base::in | std::ios_base::out);

A version of the above code was posted on a website and the poster inquired.

Why doesn’t this just open a binary file and if it’s not there create one?

I vaguely remembered something about this instance and at first I thought it was in relation to where data would be written to. Replying I wrote that adding the “trunc” flag would create the file if needed [1] but also truncate the file as the flag would suggest. Once I  had actually  thought about it I came to the realisation this was just nonsense, but there was a reason for my madness.

Although the C++ standard does not mention anything about this, that I can find, I believe it is due to C’s fopen modes and that would make sense. Would a combination of both the out and in flags be equivalent to “r+” or “w+”? Personally I suspect that the default for this situation is “r+” and by adding the truncate flag it becomes “w+”.

Yet I wonder if this is reliable across all platforms?

[1] If you have the correct privalages and the location is not on a read only disc etc.

Interesting C++ error.

Posted in C++, Development on April 6th, 2009

picard-facepalm

Whilst compiling code using g++ I came across an error that a static constant member was not defined. The member in question was of integer type being defined in-line in the class, I took one look and could see the error even thought I had never personally come into contact with this before. How? Well I am a bit of a geek when it comes to the standard and often read it so that I can produce standard conforming (or better conforming) code.

Whilst writing this post I tried to create a minimal example which shows the error; yet I can not produce a simple example that fails so the code posted here is only to demonstration code. invalid_id is the point of interest

Header file:

namespace Bar
{
	typedef unsigned int Id;
}
class Foo
{
public:
	typedef Bar::Id Id;
	static const Id invalid_id = Id(~0);
	Foo(Id id);
	Id m_id;
};

Foo* foo_create();

Source file:

Foo::Foo(Id id):m_id(id){}
Foo* foo_create()
{
	return new Foo(Foo::invalid_id);
}

The problem is that according to the standard [1] an integral static constant class member can be declared and initialised in line yet it still requires a separate definition. Until this time neither g++ or MSCV has complained about not having it so I have never included it.

const Foo::Id Foo::invalid_id;

Upon inserting the above line in the source file so that g++ would compile and then testing with Visual Studio it produces warnings like the following:

warning LNK4006: “public: static unsigned int const X::Y” … already defined in Z.obj; second definition ignored

Where X,Y and Z have been substituted in for ease of reading.

A couple of these warnings are produced which is fine you can just ignore then as the compiler is doing the same. This is until you get to  linking the library into an executable at which point it then spits out an error.

… error LNK2005: “public: static unsigned int const X::Y” … already defined in Z.obj

I have resorted to using the preprocessor to remove it from Visual Studio builds as I feel this is an MSCV error, if you know otherwise please inform me, and the solutions to the problem which MSDN provides do not seem valid for this code.

[1]

9.4.2.4

If a static data member is of const integral or const enumeration type, its declaration in the class definition can specify a constant-initializer which shall be an integral constant expression (5.19). In that case, the member can appear in integral constant expressions. The member shall still be defined in a namespace scope if it is used in the program and the namespace scope definition shall not contain an initializer.