Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Symbian OS Explained - Effective C++ Programming For Smartphones (2005) [eng].pdf
Скачиваний:
60
Добавлен:
16.08.2013
Размер:
2.62 Mб
Скачать

SUMMARY

263

and reduces the option for reuse at a later stage, should this condition no longer apply.

If the caller is passing data from a source that it does not directly control, say a communications link, there is always a possibility for invalid input to your code. In these circumstances, it’s better to handle bad incoming data by returning an error or leaving. It is unusual to use assertions under these conditions, although code may occasionally need to do so, depending on the circumstances in which it is used. Whatever the decision, ignoring the problem of illegal input is not an option!

Use defensive coding techniques to protect your functions against invalid input from calling code. __ASSERT_ALWAYS should be used to protect against illegal input that can only ever have arisen through a bug in the caller.

16.3 Summary

This chapter discussed assertion statements on Symbian OS in terms of how they work, what they do and how you should use them. Their primary purpose is for you to verify program logic as you write code and to detect bugs at the point they occur so you can find and fix them. For this reason, assertion statements must terminate the flow of execution upon failure, typically with a panic.

The chapter recommended using __ASSERT_DEBUG or ASSERT statements liberally in your code to check its internal state. You should expect to test your code thoroughly and fix defects before release, so you shouldn’t need to use __ASSERT_ALWAYS to check the internals of your code. A user, or another software developer using your code, expects you to have debugged your code; they don’t want to do it for you. Furthermore, you should think carefully before adding assertion statements to release code because of the added code size and extra execution overhead associated with them.

You should make the distinction between bugs and exceptions (failures occurring under exceptional circumstances). While you can use assertions to catch bugs, you should handle exceptions gracefully, since they may occur legitimately in your code, albeit as an atypical path of execution. This point extends to your client’s code – you should program defensively and consider whether invalid input has arisen because of a bug or exception in the caller. If it can only be due to a bug, it is acceptable to use __ASSERT_ALWAYS statements in your code to indicate to the client that they have a programming error which needs fixing. However, since release build assertion statements have a cost in terms of size, speed and

264

BUG DETECTION USING ASSERTIONS

ugly code termination, I advise you to consider carefully before using them against invalid input data which may have arisen from an exception that the caller can handle more gracefully.

This chapter illustrated some aspects of defensive programming besides the use of assertion statements, but added this note of caution. You should consider carefully how much defensive code to use, and whether it varies between debug and release builds. It can create additional complexity in your code, leaving it open to its own set of bugs, and, if you check parameter data for every possible error, it can also make your code slow and bloated. You should take care to use defensive techniques where they are most effective, and document them clearly so the client can build their own bug catching and exception handling around them.

The paradox is that you want problems to be noticeable so they are flagged up during development, but you want them to be inconspicuous in your production code. You should consider your approach to defensive code and assertions appropriately for each project you work on. In all cases, it’s best to keep it consistent and consider error handling as an important issue to be determined and defined at an architectural level.

The next chapter discusses useful debug macros and test classes on Symbian OS for tracking down programming errors such as memory leaks and invalid internal state. You can find more information about handling leaves (Symbian OS exceptions) in Chapter 2.