FOST.3™ is around 650,000 lines of code (excluding comments etc., but including the applications built using it). Changing compilers on anything that big is a big task, which is why we've been putting it off.
It turns out though that the major differences between the 2003 C++ and the 2005 C++ compilers are pretty trivial from our perspective. It picked up a few extra compliance issues and security warnings — this affected less than 20 lines of code all in. This is partly because the main changes it wanted to make to project settings are ones we've been using all along anyway.
There was one regression though that took quite some head scratching to work out. I can hardly believe that the compiler was actually doing it.
All of the base types that are supported as attributes within the O/RM layer need to be able to do a whole load of things. For example, we need to be able to convert them to string, display them honouring user preferences, generate HTML forms and read values out of the forms. Generally we provide a template function that performs the task and then specialise it where needed. Here's the one that generates HTML for a given user (I've not given all of the specialisations, just enough to give a feel for it).
namespace FSLib { // Turns anything into a user formatted string template< typename T > wstring userString( const T &t, const HTML::Attributes &/*options*/ ) { return HTML::Translator::escapeHTML( toString< T >( t ) ); } // Output items in a user handleable way template<> wstring F3BASE_DECLSPEC userString< bool >( const bool &, const HTML::Attributes & ); template<> wstring F3BASE_DECLSPEC userString< int >( const int &, const HTML::Attributes & ); template<> wstring F3BASE_DECLSPEC userString< long >( const long &, const HTML::Attributes & ); template<> wstring F3BASE_DECLSPEC userString< float >( const float &, const HTML::Attributes & ); template<> wstring F3BASE_DECLSPEC userString< Time >( const Time &, const HTML::Attributes & ); template<> wstring F3BASE_DECLSPEC userString< Date >( const Date &, const HTML::Attributes & ); template<> wstring F3BASE_DECLSPEC userString< TimePeriod >( const TimePeriod &, const HTML::Attributes & ); template<> wstring F3BASE_DECLSPEC userString< DatePeriod >( const DatePeriod &, const HTML::Attributes & ); }
The F3BASE_DECLSPEC
is there to generate the right DLL handling for importing and exporting.
The specialisation for bool
is this:
wstring FSLib::userString< bool >( const bool &b, const HTML::Attributes &options ) { if ( b ) { return userString< wstring >( options[ L"true" ].value( L"Yes" ), HTML::Attributes( options, L"true" ) ); } else { return userString< wstring >( options[ L"false" ].value( L"No" ), HTML::Attributes( options, L"false" ) ); } }
The handling of options
allows us to customise the text displayed to the user.
We have all of the basic specialisations in a single file called user.string.cpp
and this was causing problems. The compiler kept giving us an error like this:
1>Compiling… 1>user.string.cpp 1>.\user.string.cpp(34) : fatal error C1004: unexpected end-of-file found
If we commented out various ones or moved them around we'd always get the same error on the second specialisation. Here is the workaround we found for bool
:
wstring FSLib::userString< bool >( const bool &b, const HTML::Attributes &options ) { if ( b ) { return userString< wstring >( options[ L"true" ].value( L"Yes" ), HTML::Attributes( options, L"true" ) ); } else { return userString< wstring >( options[ L"false" ].value( L"No" ), HTML::Attributes( options, L"false" ) ); } };
Spot the difference? We had to add a semi-colon to the end of the function definition. I'm pretty sure that this is just wrong, but there you have it.