Assert is the best way. Assert that doesn't terminate the program is even better, so that a coworker can continue to test his code without being blocked by your function stubs, and he stays perfectly informed about what's not implemented yet.
In case that your IDE doesn't support smart asserts or persistent breakpoints here is simple implementation (c++):
#ifdef _DEBUG
// 0xCC - int 3 - breakpoint
// 0x90 - nop?
#define DebugInt3 __emit__(0x90CC)
#define DEBUG_ASSERT(expr) ((expr)? ((void)0): (DebugInt3) )
#else
#define DebugInt3
#define DEBUG_ASSERT(expr) assert(expr)
#endif
//usage
void doStuff()
{
//here the debugger will stop if the function is called
//and your coworker will read your message
DEBUG_ASSERT(0); //TODO: will be implemented on the next week;
//postcondition number 2 of the doStuff is not satisfied;
//proceed with care /Johny J.
}
Advantages:
- code compiles and runs
- a developer get a message about what's not implemented if and only if he runs into your code during his testing, so he'll not get overwhelmed with unnecessary information
- the message points to the related code (not to exception catch block or whatever). Call stack is available, so one can trace down the place where he invokes unfinished piece of code.
- a developer after receiving the message can continue his test run without restarting the program
Disadvantages:
- To disable a message one have to comment out a line of code. Such change can possibly sneak in the commit.
P.S. Credits for initial DEBUG_ASSERT implementation go to my co-worker E. G.