C++.Coding.Standards.1918.Rules.Guidelines [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

C++.Coding.Standards.1918.Rules.Guidelines [Electronic resources] - نسخه متنی

Herb Sutter, Andrei Alexandrescu

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید


Discussion


It's hard enough to find an error in your code when you're looking for it; it's even harder when you've assumed your code is error-free.

Steve McConnell

It is hard to overestimate the power of assertions. The

assert macro and alternatives such as compile-time (and, less preferably, run-time) assertion templates are invaluable tools for detecting and debugging programming errors during a project's development. Of all such tools, they arguably have the best complexity/effectiveness ratio. The success of a project can be conditioned at least in part by the effectiveness with which developers use assertions in their code.

Assertions commonly generate code in debug mode only (when the

NDEBUG macro is not defined), so they can be made "free" in release builds. Be generous with what you check. Never write expressions with side effects in

assert statements. In release mode, when the

NDEBUG macro is defined,

assert s don't generate any code at all:

assert( ++i < limit );

// bad: i is incremented in debug mode only

According to information theory, the quantity of information in an event is inversely proportional to the likelihood of that event happening. Thus, the less likely some

assert is to fire, the more information it will bring to you when it does fire.

Avoid

assert(false) , and prefer

assert( !"informational message" ) . Most compilers will helpfully emit the string in their error output. Also consider adding

&& "informational message" to more complex assertions, especially instead of a comment.

Consider defining your own

assert . The standard

assert macro unceremoniously aborts the program with a message to the standard output. Your environment likely offers enhanced debugging capabilities; for example, it might allow starting an interactive debugger automatically. If so, you may want to define your own

MYASSERT macro and use it. It can also be useful to retain most assertions even in release builds (prefer not to disable checks for performance reasons unless there's a proven need; see Item 8), and there is real benefit to having an assertion facility that can distinguish between "levels" of assertions, some of which stay on in release mode.

Assertions often check conditions that could be verified at compile time if the language were expressive enough. For example, your whole design might rely on every

Employee having a nonzero

id_ . Ideally, the compiler would analyze

Employee 's constructor and members and prove by static analysis that, indeed, that condition is always true. Absent such omniscience, you can issue an

assert( id_ != 0 ) inside the implementation of

Employee whenever you need to make sure an

Employee is sane:

unsigned int Employee::GetID() {

assert( id_ != 0 && "Employee ID is invalid (must be nonzero)" );
return id_;
}

Don't use assertions to report run-time errors (see Items 70 and 72). For example, don't use

assert to make sure that

malloc worked, that a window creation succeeded, or that a thread was started. You can, however, use

assert to make sure that APIs work as documented. For example, if you call some API function that is documented to always return a positive value, but you suspect it might have a bug, plant an

assert after the call to validate its postcondition.Items 69 to 75). For everything else that shouldn't, and it's the programmer's fault if it does, there is

assert .


/ 521