- Overview
-
Table of Contents
- Special Member Functions: Constructors, Destructors, and the Assignment Operator
- Operator Overloading
- Memory Management
- Templates
- Namespaces
- Time and Date Library
- Streams
- Object-Oriented Programming and Design Principles
- The Standard Template Library (STL) and Generic Programming
- Exception Handling
- Runtime Type Information (RTTI)
- Signal Processing
- Creating Persistent Objects
- Bit Fields
- New Cast Operators
- Environment Variables
- Variadic Functions
- Pointers to Functions
- Function Objects
- Pointers to Members
- Lock Files
- Design Patterns
- Dynamic Linking
- Tips and Techniques
- Five Things You Need to Know About C++11 Unions
- A Tour of C99
- A Tour of C1X
-
C++0X: The New Face of Standard C++
- Reference Wrapper
- The Performance Technical Report
- auto for the People
- Ironing Templates' Syntactic Wrinkles
- Visual C++ Becomes ISO Compliant
- A Garbage Collector for C++
- C99 Core Features in C++0X
- The <code>shared_ptr</code> Class
- The shared_ptr Class, II
- Lambda Expressions and Closures, Part I
- Lambda Expressions and Closures, Part II
- Lambda Expressions and Closures, Part III
- The Type Traits Library, Part I
- The Type Traits Library, Part II
- The Type Traits Library, Part III
- finally Revisited
- The Any Library
- The nullptr Keyword Proposal
- Delegating Constructors
- The Explicit Conversion Operators Proposal
- Conditionally-Supported Behavior
- The weak ptr Class Template, Part I
- The weak ptr Class Template, Part II
- POD Types Revisited
- The rvalue Reference Proposal, Part I
- The rvalue Reference Proposal, Part II
- Proposal for New String Algorithms
- Concepts, Part I
- Concepts, Part II
- constexpr: Generalized Constant Expressions
- The <u>constexpr</u> Proposal: Constructors
- Strongly-Typed enum Types
- C++09: The Road Ahead
- C++09: Proposals by Statuses
- Changing Undefined Behavior to Diagnosable Errors
- New Character Types
- The __func__ Predeclared Identifier is Coming to C++
- Static Assertions
- The extern template Proposal
- Variadic Templates, Part I
- Variadic Templates, Part II
- Variadic Templates, Part III -- Critique
- Using unique_ptr, Part I
- Using unique_ptr, Part II
- Unrestricted Unions, Part I
- Unrestricted Unions, Part II
- Unrestricted Unions, Part III
- Types With No Linkage as Template Arguments
- New Initialization Syntax
- Initializer Lists and Sequence Constructors
- New Standard Library Algorithms
- Class Member Initializers
- Inheriting Constructors
- Introducing Attributes
- The Removal of Concepts From C++0x
- The Future of C++0x, Part I
- The Future of C++0X, Part II
- The Debate About Attributes, Part I
- The Debate About Attributes, Part II
- The Debate About Attributes, Part III
- The Debate About Attributes, Part IV
- Forward Declarations of Enum Types
- The SCARY Iterators Proposal, Part I
- The SCARY Iterators Proposal, Part II
- Heading for Deprecation: <tt>export</tt>, Exception Specification and <tt>register</tt>
- The Rejection of the Unified Function Syntax Proposal
- Rvalue References as Object Members
- FCD Approved
- The Debate on noexcept, Part I
- The Debate on noexcept, Part II
- The Debate on noexcept, Part III
- About-face -- [[Attributes]] to Be Replaced with Keywords
- Will Delegating Constructors Be Removed From C++0x?
- Rvalue References: Past, Present and Future, Part I
- Rvalue References: Past, Present and Future, Part II
- Rvalue References: Past, Present and Future, Part III
- A Move in the Right Direction, Part I
- A Move in the Right Direction, Part II
- New Keywords for Inheritance Control, Part I
- New Keywords for Inheritance Control, Part II
- FDIS Approved
- C++0x Concurrency
- The Reflecting Circle
- We Have Mail
- The Soapbox
- Numeric Types and Arithmetic
- Careers
- Locales and Internationalization
Static Assertions
Last updated Jan 1, 2003.
C++09 introduces a new keyword, static_assert that operates more or less as the assert() macro except that it's evaluated at compile-time. Find out here what static_assert is used for and how it differs from concepts.
assert() And #error
C++03 already supports two facilities for testing software assertions:
- assert()
- #error
Neither of these is suitable for template programming. The assert() macro is evaluated at runtime, which is too late for examining a template specialization failure. By contrast, the #error preprocessor directive is evaluated during the preprocessing stage, which is too early for looking into template specializations.
C++ libraries that use templates extensively (is there any serious C++ library these days that doesn't?) need a mechanism for testing software assertions at compile-time. The solution is a new assertion facility that is evaluated when template specializations are processed. More specifically, the design requirements of the new assertion facilities are:
- The assertion evaluation must be performed during compile time. No runtime cost or space overhead are acceptable.
- The assertion facility must have simple and intuitive syntax.
- An assertion failure must result in a meaningful and informative error message.
- An assertion can be used at namespace, class, or block scope.
To meet all of these requirements and improve the detection of compile-time assertion failures, C++09 introduces a new keyword called static_assert. A static_assert declaration may appear anywhere a using-declaration is allowed. A static_assert declaration has the following form:
static_assert (integral-constant-expression, string-literal);
If the constant-expression in the static assertion evaluates as 0 (i.e., an assertion failure), the compiler will issue a diagnostic message containing the string literal provided as the second argument. Otherwise, the static_assert has no effect. A static_assert-declaration shall not declare a new type or object. It does not imply any size or time cost at runtime.
Scope
A static_assert declaration can appear at a namespace scope, block scope, and class member declaration lists. When used at a namespace scope, a static_assert declaration may replace the #error preprocessor directive. For example, the following static_assert declaration ensures that the implementation supports 64-bit addressing:
static_assert(sizeof(void*) >= 8, "64-bit addressing is required for this program");
A static_assert declaration at a class scope enables the implementer to enforce certain requirements on the said class. The following string template requires that the type CharT shall be a POD type:
template <class CharT, class Traits = std::char_traits<CharT> >
class basic_string
{
static_assert(tr1::is_pod<CharT>::value, "Argument CharT must be a POD type");
};
When the compiler creates an instance of basic_string<T> it checks whether the template argument is a POD type. If this isn't the case, compilation is aborted with the error message provided as the second argument.
Finally, a static_assert declaration may appear at a block scope. The main advantage of such static_assert declarations is that you can confine them to specific blocks in the program. Thus, a member function can use a local static assertion to enforce a certain requirement while the remaining member functions of the same class remain independent of that requirement. In the following example, the member function Client::func() uses static_assert to verify that the local type MemoryPage occupies the exact same size of a system virtual memory page:
#include "systempagesize.h"
class Client {
public:
int func()
{
struct MemoryPage
{
//...
};
static_assert(sizeof(MemoryPage) == PAGESIZE,
"MemoryPage must occupy exactly the same size of a system memory page");
// ...
}
// ...
};
Concepts and static_assert
Seemingly, static_assert's roles resemble those of concepts. However, there is no overlap between the two. Concepts do not eliminate the need for static_assert because static_assert can be useful in programs that do not use templates (recall that concepts are used with templates exclusively). In addition, static_assert combined with type traits enable the implementer to diagnose errors that concepts cannot detect. Take for example the requirement that CharT shall be a POD type. Using constraints alone, it's difficult to express this constraint. Furthermore, in some cases, expressing requirements such as 64-bit addressing with static_assert seems more intuitive than writing a full-blown constraint.
Presently, several compilers implement static_assert including IBM, MetroWerks, Comeau and GCC 3.3
