Posts Tagged MFC
Nice bug I had with virtual functions in C++
Yesterday I asked to take a look to one bug in our application. Some application feature which was always worked, stopped working. The guy who last touched this part of application, said it is not his fault, and and he didn’t done something that could affect this feature. After 9 hours investigation, I found the problem, and it was so interesting, so I decided to write about it.
Suppose, you have base class ‘BaseClass’, and it defines some virtual method ‘SomeMethod’. All classes derived from BaseClass override this method. For example
class BaseClass
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class A
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class B
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class C
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
… and so on. About 10 classes in different places inside very large and complicate application. In some place in application you call these methods:
for(int i=0; i<10; i++)
{
BaseClass baseClass = (BaseClass ) someClass;
baseClass.SomeMethod(0,0);
}
In for loop above, we using polymorphism to call to right function for each someClass object. So far so good.
Now some guy, decided to add additional parameter to SomeMethod in base class. But he didn’t updated all derived classes, but some of them. The result was as following:
class BaseClass
{
public:
virtual void SomeMethod(int arg1, int arg2, int arg3);
};
class A
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
class B
{
public:
virtual void SomeMethod(int arg1, int arg2, int arg3);
};
class C
{
public:
virtual void SomeMethod(int arg1, int arg2);
};
You see what wrong? Now the method signature in classes A and C differs from one in BaseClass, and therefore polymorphism not working anymore. All they do are declaring virtual functions of their own. So in loop above, when we cast class A to BaseClass, and calling to SomeMethod – actually we calling to method in the base class. This situation however, is not possible in C#: to override virtual functions we use keyword ‘override’, and in case base method signature will change, we will get error during compilation. By the way, even if base method and override method differs only by ‘const’ keyword – this is good enough to kill polymorphism.
Add comment December 28, 2007
Is using memcpy worth it in .NET ?
Recently, I decided to boost my .NET / MFC serialization. Instead of copying object fields field by field, I would like use memcpy to speedup this process. However, it is not trivial at all to use memcpy in .NET, because the code is managed, and you have no control over the managed types. You can however, override this by using many tricks, such as converting reference types to value, by generating special structures and so on. However this makes code very hard to maintenance, and difficult to debug. So the main question is: Is it worth to do all this just to use memcpy, instead of copying field by field?
To answer this, I created very simple application. I copying struct with 5 fields by 2 ways: using memcpy, and second is coping field by field. I repeating coping in loop, for big number of iterations (in my example – 300000000 iterations). I measuring time in each way. Here is average results that I got (Windows XP, AMD athlon 64 dual core):
Compiled in debug mode: Coping using memcpy: 9500ms , Coping field by field: 1750ms.
Compiled in release mode (disabling optimizations) – same as in debug mode.
Compiled in release mode (optimize: minimize size): Coping using memcpy: 7050ms, Coping field by field: 0ms
Compiled in release mode (optimize: maximize speed): Coping using memcpy: 0ms, Coping field by field: 0ms. I suspect that because of optimization, it not entering my loop at all.
Compiled in release mode (optimize: full optimization) – Same as optimize: maximize speed.
When my friend tried the same on Intel 32 bit machine, he said memcpy performed faster in about 300 ms than coping field by field.
Conclusion: as you can see, the difference in performance is very minor (in such a high rate of coping). Therefore, unless you know some nice and clear way to use memcpy in .NET, it NOT worth the overhead to use it.
3 comments December 21, 2007