Monday, October 31, 2005

VS2005 issues

In my last post I mentioned that VS2005 was tighter than its predecessor. I thought it'd be useful to show where we had some problems (we're still working through them so this isn't an exhaustive list) and some of our solutions.

The changes are all covered in detail in the MSDN document "Breaking Changes in the Visual C++ 2005 Compiler" but I'll try and give some real examples that we faced.

Pointer-to-members now require qualified name and &

The compiler is much stricter about the types of function pointers. The error C3867 is generated with the following code:

: m_MyObserver(this, MyCallback)
The resolution is to qualify the function pointers and pass the addressof the function in. e.g.
: m_MyObserver(this, &CAThing::MyCallback)

const_cast can't down cast / Previously implicit string
casts are no longer allowed

This code does not compile (error C2440)
   BSTR bstrMessage = SysAllocString(T2OLE(const_cast(MyThing.ErrorMessage.c_str())));
This was replaced with the following (the BSTR could be deallocated after use):
   CComBSTR bstrMessage(MyThing.ErrorMessage.c_str());
This code will also give the same error:
   OLECHAR* pStringBuffer;
USHORT* pString = pStringBuffer;

COM/C++ Attributes with enumeration values should not be enclosed in quotes.

This code:
Should be rewritten without the quotes as:
The first time that the quotes get compiled gives warning C4581. This implies that the double quotes (") need to be replaced with single quotes ('). However, if you do this you then get error C3455. This error will say that "none of the attribute constructors matched the arguments".

Public attributes are stricter

The error MIDL2072 will be emitted for this code:
    typedef [public] enum EEventIdType
} EEventIdType;
The solution is to place the public attribute earlier:
    [public] typedef enum EEventIdType

The scope of variables in control constructs is limited to
the construct

In this code:
    for (int i = 0; i*max  ;++i)

The scope of i is limited to the for loop. (The * is meant to be a less than operator but I'll be damned if I can get blogger to cooperate!)

Method declarations must explicitly indicate return types

This code gives the error C4430:
    virtual CheckChar(UINT maskChar, UINT nChar, int endPos);
The return type must be explicitly defined. e.g.
    virtual int CheckChar(UINT maskChar, UINT nChar, int endPos);

Private types are not accesible outside of the class they
are declared in

This code gives the error C2248:
    class cdxCSizingPropSheet : public CPropertySheet
struct StandardControls

static struct cdxCSizingPropSheet::StandardControls psheetCtrls[] =
In this example, the struct StandardControls needs to be available at the global scope for psheetCtrls.

Deprecated methods

For security, many methods/functions that can cause buffer overruns have been deprecated. The recommended action is:
  • replace the deprecated methods, or
  • define _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES as 1 so the compiler will use a template overload to replace the deprecated method with another. N.B. security template overloads are not available for everything. Alternatively,
  • define _CRT_SECURE_NO_DEPRECATE or the warning pragma to not display this warning.
If you want my opinion (sure you do!) any function that can cause buffer overruns ought to be an error and avoided. You'll thank me later. ;)

OK, that's it for now. We had a few more but I've had it with trying to lay out code in Blogger. Does anyone know any good blogging software to write code? It's damn hard from within the Blogger editor. I'm thinking of moving to my own system hosted at home for this reason alone (actually there are a few more!). If I was to move to my own system which can you recommend that do a good job of handling code?

Anyway, I hope that was useful to you - and a huge thanks to Ben who wrote most of this in our Wiki at work. The good work was his, the errors mine. :)

1 comment:

Anonymous said...
This comment has been removed by a blog administrator.