Surprise of the week
There is no doubt that programmers are very creative creatures. The more lazy they are the more astonishing stuff they can create. This short post is just about a piece of code that I have found in some project. Before I step into details I'd like to provide you some background.
Everyone knows that C++ macros are evil. There are many techniques that can help avoid them, but in some situations it's just not worth to apply these techniques. Such a situation would be allowing mocks to unit test production code. I'm not going to discuss whether it is good or bad to use mocks, but they have one small flaw - when you want to use them you probably will have to make methods virtual.
And this is our problem here - how to make this happen only on test builds? We surely don't want our production code to use vtables just-because. This is where some ifdefs can actually save the day:
In above example happyMethod will be virtual only when UT flag is passed to the compiler. Thus, it can be mocked with GTest's StrictMock, for instance.
This is pretty straightforward. Also, if it is used correctly, side effects are not supposed to happen. So now, when you have some background please have a look at the following.
This is not even similar thing. The object that is passed to the method is either constant or not - depending on build type. I can't imagine how many side effects this may have.
Everyone knows that C++ macros are evil. There are many techniques that can help avoid them, but in some situations it's just not worth to apply these techniques. Such a situation would be allowing mocks to unit test production code. I'm not going to discuss whether it is good or bad to use mocks, but they have one small flaw - when you want to use them you probably will have to make methods virtual.
And this is our problem here - how to make this happen only on test builds? We surely don't want our production code to use vtables just-because. This is where some ifdefs can actually save the day:
1 #ifdef UT
2 # define MOCKABLE virtual
3 #else
4 # define MOCKABLE
5 #endif
6
7 struct MockableClass {
8 MOCKABLE happyMethod() const;
9 };
In above example happyMethod will be virtual only when UT flag is passed to the compiler. Thus, it can be mocked with GTest's StrictMock, for instance.
This is pretty straightforward. Also, if it is used correctly, side effects are not supposed to happen. So now, when you have some background please have a look at the following.
1 #ifdef UT
2 # define CONST
3 #else
4 # define CONST const
5 #endif
6
7 struct WeirdClass {
8 void notReallyHappyMethod(Object CONST object);
9 };
This is not even similar thing. The object that is passed to the method is either constant or not - depending on build type. I can't imagine how many side effects this may have.