diff --git a/src/content/docs/cpp/language/exceptions.mdx b/src/content/docs/cpp/language/exceptions.mdx new file mode 100644 index 0000000..cbd54d9 --- /dev/null +++ b/src/content/docs/cpp/language/exceptions.mdx @@ -0,0 +1,82 @@ +--- +title: Exceptions +cppdoc: + keys: ["cpp.lang.exceptions"] +--- + +import { Decl, DeclDoc } from "@components/decl-doc"; +import { Desc, DescList, DocLink } from '@components/index'; +import { Revision, RevisionBlock } from "@components/revision"; +import { DR, DRList } from "@components/defect-report"; +import { ParamDoc, ParamDocList } from "@components/param-doc"; +import { FeatureTestMacro, FeatureTestMacroValue } from "@components/feature-test-macro"; + +Exception handling provides a way of transferring control and information from some point in the execution of a program to a handler associated with a point previously passed by the execution (in other words, exception handling transfers control up the call stack). + +Evaluating a `throw` expression will throw an exception. Exceptions can also be thrown in other contexts. + +In order for an exception to be caught, the `throw` expression has to be inside a `try` block, and the `try` block has to contain a handler that matches the type of the exception object. + +When declaring a function, the following specification(s) may be provided to limit the types of the exceptions a function may throw: + +- dynamic exception specifications +- noexcept specifications + +Errors that arise during exception handling are handled by `std::terminate` and `std::unexpected`. + +## Usage + +While `throw` expression can be used to transfer control to an arbitrary block of code up the execution stack, for arbitrary reasons (similar to `std::longjmp`), its intended usage is error handling. + +### Error handling + +Throwing an exception is used to signal errors from functions, where "errors" are typically limited to only the following[^1] [^2] [^3]: + +1. Failures to meet the postconditions, such as failing to produce a valid return value object. +2. Failures to meet the preconditions of another function that must be called. +3. (for non-private member functions) Failures to (re)establish a class invariant. + +In particular, this implies that the failures of constructors (see also RAII) and most operators should be reported by throwing exceptions. + +In addition, so-called *wide contract* functions use exceptions to indicate unacceptable inputs, for example, `std::basic_string::at` has no preconditions, but throws an exception to indicate index out of range. + +### Exception safety + +After the error condition is reported by a function, additional guarantees may be provided with regards to the state of the program. The following four levels of exception guarantee are generally recognized[^4] [^5] [^6], which are strict supersets of each other: + +1. *Nothrow (or nofail) exception guarantee* — the function never throws exceptions. Nothrow (errors are reported by other means or concealed) is expected of destructors and other functions that may be called during stack unwinding. The destructors are `noexcept` by default. Nofail (the function always succeeds) is expected of swaps, move constructors, and other functions used by those that provide strong exception guarantee. +2. *Strong exception guarantee* — If the function throws an exception, the state of the program is rolled back to the state just before the function call (for example, `std::vector::push_back`). +3. *Basic exception guarantee* — If the function throws an exception, the program is in a valid state. No resources are leaked, and all objects' invariants are intact. +4. *No exception guarantee* — If the function throws an exception, the program may not be in a valid state: resource leaks, memory corruption, or other invariant-destroying errors may have occurred. + +Generic components may, in addition, offer *exception-neutral guarantee*: if an exception is thrown from a template parameter (e.g. from the `Compare` function object of `std::sort` or from the constructor of `T` in `std::make_shared`), it is propagated, unchanged, to the caller. + +## Exception objects + +While objects of any complete type and cv pointers to `void` may be thrown as exception objects, all standard library functions throw unnamed objects by value, and the types of those objects are derived (directly or indirectly) from `std::exception`. User-defined exceptions usually follow this pattern.[^7] [^8] [^9] + +To avoid unnecessary copying of the exception object and object slicing, the best practice for handlers is to catch by reference.[^10] [^11] [^12] [^13] + +## Notes + + + + `constexpr` exceptions + + + +## External links + +[^1]: H. Sutter (2004) [When and How to Use Exceptions](https://www.drdobbs.com/when-and-how-to-use-exceptions/184401836) in Dr. Dobb's +[^2]: H. Sutter, A. Alexandrescu (2004) "C++ Coding Standards" Item 70 +[^3]: C++ Core Guidelines [I.10: Use exceptions to signal a failure to perform a required task](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Ri-except) +[^4]: B. Stroustrup (2000) "The C++ Programming Language" [Appendix E](https://stroustrup.com/3rd_safe.pdf) +[^5]: H. Sutter (2000) "Exceptional C++" +[^6]: D. Abrahams (2001) ["Exception Safety in Generic Components"](https://www.boost.org/community/exception_safety.html) +[^7]: D. Abrahams (2001) ["Error and Exception Handling"](https://www.boost.org/community/error_handling.html) +[^8]: isocpp.org Super-FAQ ["What should I throw?"](https://isocpp.org/wiki/faq/exceptions#what-to-throw) +[^9]: C++ Core Guidelines [E.14: Use purpose-designed user-defined types as exceptions (not built-in types)](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Re-exception-types) +[^10]: C++ Core Guidelines [E.15: Throw by value, catch exceptions from a hierarchy by reference](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Re-exception-ref) +[^11]: S. Meyers (1996) "More Effective C++" Item 13 +[^12]: isocpp.org Super-FAQ ["What should I catch?"](https://isocpp.org/wiki/faq/exceptions#what-to-catch) +[^13]: H. Sutter, A. Alexandrescu (2004) "C++ Coding Standards" Item 73 \ No newline at end of file diff --git a/src/content/docs/cpp/language/preprocessor.mdx b/src/content/docs/cpp/language/preprocessor.mdx new file mode 100644 index 0000000..4c29c24 --- /dev/null +++ b/src/content/docs/cpp/language/preprocessor.mdx @@ -0,0 +1,74 @@ +--- +title: preprocessor +cppdoc: + keys: ["cpp.lang.preprocessor"] +--- + +import { Desc, DescList, DocLink } from '@components/index'; +import { Revision, RevisionBlock } from "@components/revision"; +import { DR, DRList } from "@components/defect-report"; + +The preprocessor is executed at translation phase 4, before the compilation. The result of preprocessing is a single file which is then passed to the actual compiler. + +## Directives + +The preprocessing directives control the behavior of the preprocessor. Each directive occupies one line and has the following format: + +* the `#` character. +* a sequence of: + * a standard-defined directive name (listed [below](#Capabilities)) followed by the corresponding arguments, or + * one or more preprocessing tokens where the beginning token is not a standard-defined directive name, in this case the directive is conditionally-supported with implementation-defined semantics (e.g. a common non-standard extension is the directive `#warning` which emits a user-defined message during compilation), or + * nothing, in this case the directive has no effect. +* a line break. + +The module and import directives are also preprocessing directives. + +Preprocessing directives must not come from macro expansion. + +```cpp +#define EMPTY +EMPTY # include // not a preprocessing directive +``` + +## Capabilities + +The preprocessor has the source file translation capabilities: + +* **conditionally** compile parts of source file (controlled by directive `#if`, `#ifdef`, `#ifndef`, `#else`, `#elif`, `#elifdef`, `#elifndef`, and `#endif`). +* **replace** text macros while possibly concatenating or quoting identifiers (controlled by directives `#define` and `#undef`, and operators `#` and `##`). +* **include** other files (controlled by directive `#include` and checked with `__has_include` ). +* cause an **error** or **warning** (controlled by directive `#error` or `#warning` respectively). + +The following aspects of the preprocessor can be controlled: + +* **implementation-defined** behavior (controlled by directive `#pragma` and operator `_Pragma` ). In addition, some compilers support (to varying degrees) the operator `__pragma` as a *non-standard* extension. +* **file name and line information** available to the preprocessor (controlled by directive `#line`). + +## Defect reports + +The following behavior-changing defect reports were applied retroactively to previously published C++ standards. + + + + + the behavior of using non-standard-defined directives was not clear + + + made conditionally-supported + + + + +## See also + + + +C++ documentation for Predefined Macro Symbols + + +C++ documentation for Macro Symbol Index + + +C documentation for preprocessor + + \ No newline at end of file diff --git a/src/content/docs/cpp/language/templates.mdx b/src/content/docs/cpp/language/templates.mdx new file mode 100644 index 0000000..cc5eb20 --- /dev/null +++ b/src/content/docs/cpp/language/templates.mdx @@ -0,0 +1,282 @@ +--- +title: Templates +cppdoc: + keys: ["cpp.lang.templates"] +--- + +import { Decl, DeclDoc } from "@components/decl-doc"; +import { Desc, DescList, DocLink } from '@components/index'; +import { Revision, RevisionBlock } from "@components/revision"; +import { DR, DRList } from "@components/defect-report"; +import { ParamDoc, ParamDocList } from "@components/param-doc"; + +A template is a C++ entity that defines one of the following: + +- a family of classes (class template), which may be nested classes +- a family of functions (function template), which may be member functions + + +- an alias to a family of types (alias template) + + +- a family of variables (variable template) + + +- a concept (constraints and concepts) + +Templates are parameterized by one or more template parameters, of three kinds: type template parameters, constant template parameters, and template template parameters. + +When template arguments are provided, or, for function and class templates only, deduced, they are substituted for the template parameters to obtain a *specialization* of the template, that is, a specific type or a specific function lvalue. + +Specializations may also be provided explicitly: full specializations are allowed for class, variable and function templates, partial specializations are only allowed for class templates and variable templates. + +When a class template specialization is referenced in context that requires a complete object type, or when a function template specialization is referenced in context that requires a function definition to exist, the template is *instantiated* (the code for it is actually compiled), unless the template was already explicitly specialized or explicitly instantiated. Instantiation of a class template does not instantiate any of its member functions unless they are also used. At link time, identical instantiations generated by different translation units are merged. + +The definition of a class template must be visible at the point of implicit instantiation, which is why template libraries typically provide all template definitions in the headers (e.g., [most boost libraries are header-only](https://www.boost.org/doc/libs/release/more/getting_started/unix-variants.html#header-only-libraries)). + +## Syntax + + + + ```cpp + template requires-clause(optional) declaration + ``` + + + + + + ```cpp + export template declaration + ``` + + + + + + + ```cpp + template concept concept-name = constraint-expression; + ``` + + + + + + + + a non-empty comma-separated list of the template parameters, each of which is either constant parameter, a type parameter, a template parameter, or a parameter pack of any of those(since C++11). + + + (since C++20) a requires-clause that specifies the constraints on the template arguments. + + + declaration of a class (including struct and union), a member class or member enumeration type, a function or member function, a static data member at namespace scope, a variable or static data member at class scope(since C++14), or an alias template(since C++11). It may also define a template specialization. + + + concept-name + + + see constraints and concepts + + + +export was an optional modifier which declared the template as exported (when used with a class template, it declared all of its members exported as well). Files that instantiated exported templates did not need to include their definitions: the declaration was sufficient. Implementations of export were rare and disagreed with each other on details. +> This section is incomplete.\ +> **Reason:** core syntax, template parameters, and instantiations, take content common between class_template and function_template + +## Template identifiers + +A template identifier has one of the following syntaxes: + + + + ```cpp + template-name + ``` + + + A *simple template identifier*. + + + + ```cpp + operator op + ``` + + + An operator function template identifier. + + + + ```cpp + operator "" identifier + ``` + + + A literal operator function template identifier. + + + + ```cpp + operator user-defined-string-literal + ``` + + + A user-defined string literal operator. + + +A simple template identifier that names a class template specialization names a class. + +A template identifier that names an alias template specialization names a type. + +A template identifier that names a function template specialization names a function. + +If all following conditions are satisfied, a template identifier is *valid*: + +- There are at most as many arguments as there are parameters or a parameter is a template parameter pack +- There is an argument for each non-deducible non-pack parameter that does not have a default template argument +- Each template argument matches the corresponding template parameter +- Substitution of each template argument into the following template parameters (if any) succeeds + +- If the template identifier is non-dependent, the associated constraints are satisfied as specified below + +An invalid simple template id is a compile-time error, unless it names a function template specialization (in which case SFINAE may apply). + +```cpp +template +class X; + +struct S +{ + using type = int; +}; + +using T1 = X; // error: too many arguments +using T2 = X<>; // error: no default argument for first template parameter +using T3 = X<1>; // error: value 1 does not match type-parameter +using T4 = X; // error: substitution failure for second template parameter +using T5 = X; // OK +``` + + +When the `template-name` of a simple template id names a constrained non-function template or a constrained template template parameter, but not a member template that is a member of an unknown specialization, and all template arguments in the simple template id are non-dependent, the associated constraints of the constrained template must be satisfied: + +```cpp +template +concept C1 = sizeof(T) != sizeof(int); + +template +struct S1 {}; + +template +using Ptr = T*; + +S1* p; // error: constraints not satisfied +Ptr p; // error: constraints not satisfied + +template +struct S2 { Ptr x; }; // error, no diagnostic required + +template +struct S3 { Ptr x; }; // OK, satisfaction is not required + +S3 x; // error: constraints not satisfied + +template class X> +struct S4 +{ + X x; // error, no diagnostic required +}; + +template +concept C2 = sizeof(T) == 1; + +template struct S {}; + +template struct S; // error: constraints not satisfied +template<> struct S {}; // error: constraints not satisfied +``` + + +If all following conditions are satisfied, two template identifiers are *same*: + +- Their `template-name`s or operators refer to the same template +- Their corresponding type template arguments are the same type +- The template parameter values determined by their corresponding constant template arguments are template-argument-equivalent +- Their corresponding template template arguments refer to the same template + +Two template identifier that are the same refer to the same variable, class, or function. + +## Templated entity + +A *templated entity* (or, in some sources, "temploid") is any entity that is defined (or, for a lambda expression, created) within a template definition. All of the following are templated entities: + +- a class/function/variable template + + +- a concept + +- a member of a templated entity (such as a non-template member function of a class template) +- an enumerator of an enumeration that is a templated entity +- any entity defined or created within a templated entity: a local class, a local variable, a friend function, etc + +- the closure type of a lambda expression that appears in the declaration of a templated entity + +For example, in + +```cpp +template +struct A +{ + void f() {} +}; +``` + +the function `A::f` is not a function template, but is still considered to be templated. + +A *templated function* is a function template or a function that is templated. + +A *templated class* is a class template or a class that is templated. + +A *templated variable* is a variable template or a variable that is templated. + +## Keywords + +template, +export + +## Defect reports + +The following behavior-changing defect reports were applied retroactively to previously published C++ standards. + + + + + the rules of determining whether a template identifier is valid were not provided + + + provided + + + + + the definitions of templated function/template class (C++98)/templated variable (C++14) were missing + + + added + + + + + two template identifiers were different if their corresponding constant template arguments are not template-argument-equivalent + + + they are different if their corresponding constant template parameter values are not template-argument-equivalent + + + + +## See also + +C documentation for __Generic selection__ \ No newline at end of file