Imperfect C++ Practical Solutions for Real-Life Programming:Imperfections, Constraints, Definitions, and Recommendations

By Matthew Wilson

Imperfections, Constraints, Definitions, and Recommendations

Imperfection: C++ does not provide direct support for constraints. (p. 4)


Imperfection: C++ does not provide suitable support for postconditions. (p. 15)


Recommendation: Use assertions to assert truths about the structure of the code, not about runtime behavior. (p. 21)


Definition: Resource Release Is Destruction is a mechanism that takes advantage of C++'s support for automatic destruction to ensure the deterministic release of resources associated with an instance of an encapsulating type. (p. 46)


Definition: Resource Acquisition Is Initialization is a mechanism that takes advantage of C++'s support for construction and automatic destruction to ensure the deterministic release of resources associated with an instance of an encapsulating type. It can be thought of as a superset of the RRID mechanism. (p. 51)


Definition: Encapsulated types provide access to, and manipulation of, instance state via a robust public interface, and client code should not, and need not, have access to the internal member state of instances of such types. Encapsulated types provide a notionally complete separation between logical and physical state. (p. 60)


Definition: Value Type (p. 62)

Instances cannot polymorphically substitute, or be substituted by, instances of another type at run time.

Instances can be created as, or later made to be, copies of another instance.

Each instance has a logically separate identity. Any change to the logical state of one instance does not result in a change to the logical state of another. (Physical state may be shared according to implementation-specific design decisions, so long as such sharing does not invalidate the logical separation.)

Instances can be (in)equality compared with any other instances, and even with themselves. Equality (and inequality) is reflexive, symmetric, and transitive.


Imperfection: The C++ standard does not define an ABI, leading to wholesale incompatibilities between many comxpilers on many platforms. (p. 92)


Imperfection: C++ is not a suitable module-interface language. (p. 121)


Imperfection: C and C++ say nothing about threading. (p. 132)


Imperfection: C++ does not provide a mechanism for controlling global object ordering. (p. 158)


Recommendation: Don't rely on global object initialization ordering. Do utilize global object initialization ordering tracing mechanisms anyway. (p. 161)


Recommendation: Don't create threads during global object initialization. (p. 166)


Imperfection: Function-local static instances of classes with nontrivial constructors are not thread-safe. (p. 171)


Imperfection: The support for Empty Base Optimization (EBO) flavors is not universal, and varies significantly between compilers. (p. 183)


Imperfection: C and C++ are missing a byte type. (p. 191)


Imperfection: C and C++ need fixed-sized integer types. (p. 195)


Imperfection (reprise): C++ needs fixed sized types that are different to, and not implicitly interconvertible with, its built-in integral types. (p. 196)


Imperfection: C and C++ do not provide large fixed-sized integer types. (p. 200)


Imperfection: bool should be the same size as int. (p. 205)


Imperfection: C and C++ do not provide a dimensionof() operator (for array types). (p. 207)


Imperfection: Inability to distinguish between arrays and pointers can result in static array size determination being applied to pointers or class types, yielding incorrect results. (p. 211)


Imperfection: C and C++ arrays decay into pointers when passed to functions. (p. 214)


Imperfection: C++'s array/pointer duality, combined with its support for polymorphic handling of inherited types, is a hazard against which the compiler provides no assistance. (p. 218)


Imperfection: C++ does not support multi-dimensional arrays. (p. 224)


Imperfection: C++ needs a null keyword, which can be assigned to, and equality compared with, any pointer type, and with no non-pointer types. (p. 229)


Imperfection: Having more than one discrete value for the Boolean type is dangerous. (p. 236)


Imperfection: Specification of the size of integer types as implementation dependent in C/C++ reduces the portability of integer literals. (p. 238)


Imperfection: C++ compilers do not agree on the syntax for suffixes of integer literals larger than those that will fit into (unsigned) long. (p. 239)


Constraint: C and C++ do not guarantee to ensure that identical string literals will be folded within a single link unit, and cannot do so across separate link units. (p. 242)


Constraint: Casting away constness of a constant object is not legal, and will likely lead to unintended consequences. (p. 245)


Constraint: Constants of class type are evaluated as immutable global objects, rather than as compile-time constants. Failure to be mindful of this distinction is hazardous. (p. 246)


Recommendation: Avoid using enum values larger than those that will fit in an int. (p. 248)


Imperfection: C++ does not support member constants of floating-point type. (p. 249)


Constraint: C++ does not support member constants of class type. (p. 250)


Recommendation: Never attempt to simulate class-type member constants with function local static objects. (p. 251)


Imperfection: C++ does not provide access control between types involved in a composition relationship. (p. 257)


Imperfection: The introduction of new keywords into the language requires contingency mechanisms to maintain portability. (p. 268)


Imperfection: Abuse of C++'s last-known access specifier mechanism leads to code that is hard to use and hard to maintain. (p. 271)


Imperfection: Implicitly interpreting non-Boolean (sub-)expressions leads to failure to be mindful of the values of certain types, with a consequent propensity to over-engineer user-defined types. (p. 274)


Imperfection: The implicit interpretation of scalar types as Boolean in conditional statements facilitates erroneous assignment caused by syntax errors. (p. 275)


Imperfection: The contradiction between the old and new for-statement rules results in non-portable code. (p. 278)


Imperfection: for statements requiring initializers of two or more types render the new for-scoping rule irrelevant. (p. 279)


Definition: Conceptual type definitions define logically distinct types. (p. 289)


Definition: Contextual type definitions define types that correspond to well-known concepts, relative to specific contexts. Such types act as descriptions of the nature (type and/or behavior) of their host contexts. (p. 291)


Imperfection: C++ provides no type-safety for the use of conceptual defined types, except where such types have incompatible underlying types. (p. 294)


Imperfection: C++ does not support overloading on conceptually defined types, except where such types happen to have different underlying types on a particular platform. (p. 294)


Recommendation: Avoid making conceptual typedefs that are comprised of contextual typedefs. (p. 304)


Imperfection: Logically related types in C++ can, and usually do, have incompatible interfaces and operations, rendering a generalized approach to type manipulation sometimes difficult, and often impossible. (p. 341)


Definition: Attribute Shims (pp. 343344)

Attribute shims retrieve attributes or states of instances of the types for which they are defined.

The names of attribute shims take the form get_xxx, where xxx represents the particular attribute being accessed (except where they form part of a composite shim concept).

The values returned from attribute shims are always valid outside the instance of the shim, in cases where the shim is implemented by the creation of a temporary object.


Definition: Logical Shims (p. 346)

Logical shims are a refinement of attribute shims in that they report on the state of an instance to which they are applied.

The names of logical shims take the form of an interrogative coupled with the particular attribute or state being queried. Examples would be is_open, has_element, is_null.


Definition: Control Shims (p. 347)

Control shims define operations that are applied to the instances of the types for which they are defined.

The names of control shims take the form of an imperative element coupled with the particular attribute or state being modified. Examples would be make_empty dump_contents.


Definition: Conversion Shims (p. 348)

Conversion shims operate by converting instances of the range of compatible types to a single target type.

The names of attribute shims take the form to_xxx, where xxx is the name of, or represents, the target type, for example, to_int.

The values returned from conversion shims may be provided by intermediate temporary objects, so must only be used from within the expression containing the shim.


Definition: Composite Shims (p. 350)

Composite shims are a combination of two or more fundamental shim concepts.

The names of composite shims do not have a fixed convention, but rather take a name indicative of their purpose.

Composite shims obey the most restrictive rule, or combination of rules, from their constituent shims.


Definition: Access Shims (p. 351)

Access shims are a combination of Attribute and Conversion shims, which are used to access the values of the instances of the types for which they are defined.

The values may have to be synthesised via conversion shims.

The values returned from access shims may be provided by intermediate temporary objects, so must only be used from within the expression containing the shim.


Definition: Veneers (p. 364)

A veneer is a template class with the following characteristics:

  1. It derives, usually publicly, from its primary parameterizing type.

  2. It accommodates, and adheres to, the polymorphic nature of its primary parameterizing type. This means that a veneer cannot define any virtual methods of its own, though it can override those defined by its primary parameterizing type.

  3. It may not define any non-static member variables.

The consequence of 2 & 3 is that a veneer may not change the memory footprint of its primary parameterizing type, and this is achieved by virtue of the Empty Derived Optimization (EDO; see section 12.4), a very widely supported optimization. In other words, instances of a veneer composite have the same size as the primary parameterizing type.


Definition: Bolt-ins (p. 375)

Bolt-ins are template classes with the following characteristics:

  1. They derive, usually publicly, from their primary parameterizing type.

  2. They accommodate the polymorphic nature of their primary parameterizing type. Usually they also adhere to the nature, but this is not always the case, and they may define virtual methods of their own, in addition to overriding those defined by the primary parameterizing type.

  3. They may increase the footprint of the primary parameterizing type by the definition of member variables, virtual functions and additional inheritance from non-empty types.


Imperfection: The C++ template mechanism instantiates a template based on the arguments to it, and takes no account of how, or in what form, those arguments are subsequently used within the templates. This can lead to the generation of inefficient and/or erroneous code since temporary instances of class type may be created during the forwarding of arguments through the template. (p. 387)


Imperfection: Overloading operator &() breaks encapsulation. (p. 425)


Imperfection: Provision of implicit conversion operator(s) to pointer type(s) along with subscript operator(s) is non-portable. (p. 434)


Imperfection: Some C++ compilers will substitute prefix increment/decrement overloaded operators at the call site in place of absent postfix equivalents. (p.440)


Imperfection: Overloading the && and || operators for class types represents an invisible breaking of short-circuit evaluation. (p. 454)


Imperfection: C and C++ make you choose between performance and flexibility when allocating memory. (p. 476)


Imperfection: C/C++ does not support dynamically dimensioned multidimensional arrays. (p. 491)


Recommendation: An array size shim should always be used when determining the sizes of arrays, as all other approaches do not generalize for both built-in and user defined array types. (p. 505)


Imperfection: C++ does not support local functor classes (to be used with template algorithms). (p. 514)


Definition: Type Tunneling is a mechanism whereby two logically related but physically unrelated types can be made to interoperate via the use of Access Shims. The shim allows an external type to be tunnelled through an interface and presented to the internal type in a recognized and compatible form. (p. 518)


Definition: A Range represents a bounded collection of elements, which may be accessed in an incremental fashion. It encapsulates a logical rangethat is, a beginning and an end point, along with rules for how to walk through it (move from the beginning to the end point)and embodies a single entity with which client code may access the values contained within the range. (p. 521522)


Imperfection: C++ does not provide properties. (p. 531)

Imperfections, Constraints, Definitions, and Recommendations

Imperfection: C++ does not provide direct support for constraints. (p. 4)


Imperfection: C++ does not provide suitable support for postconditions. (p. 15)


Recommendation: Use assertions to assert truths about the structure of the code, not about runtime behavior. (p. 21)


Definition: Resource Release Is Destruction is a mechanism that takes advantage of C++'s support for automatic destruction to ensure the deterministic release of resources associated with an instance of an encapsulating type. (p. 46)


Definition: Resource Acquisition Is Initialization is a mechanism that takes advantage of C++'s support for construction and automatic destruction to ensure the deterministic release of resources associated with an instance of an encapsulating type. It can be thought of as a superset of the RRID mechanism. (p. 51)


Definition: Encapsulated types provide access to, and manipulation of, instance state via a robust public interface, and client code should not, and need not, have access to the internal member state of instances of such types. Encapsulated types provide a notionally complete separation between logical and physical state. (p. 60)


Definition: Value Type (p. 62)

Instances cannot polymorphically substitute, or be substituted by, instances of another type at run time.

Instances can be created as, or later made to be, copies of another instance.

Each instance has a logically separate identity. Any change to the logical state of one instance does not result in a change to the logical state of another. (Physical state may be shared according to implementation-specific design decisions, so long as such sharing does not invalidate the logical separation.)

Instances can be (in)equality compared with any other instances, and even with themselves. Equality (and inequality) is reflexive, symmetric, and transitive.


Imperfection: The C++ standard does not define an ABI, leading to wholesale incompatibilities between many comxpilers on many platforms. (p. 92)


Imperfection: C++ is not a suitable module-interface language. (p. 121)


Imperfection: C and C++ say nothing about threading. (p. 132)


Imperfection: C++ does not provide a mechanism for controlling global object ordering. (p. 158)


Recommendation: Don't rely on global object initialization ordering. Do utilize global object initialization ordering tracing mechanisms anyway. (p. 161)


Recommendation: Don't create threads during global object initialization. (p. 166)


Imperfection: Function-local static instances of classes with nontrivial constructors are not thread-safe. (p. 171)


Imperfection: The support for Empty Base Optimization (EBO) flavors is not universal, and varies significantly between compilers. (p. 183)


Imperfection: C and C++ are missing a byte type. (p. 191)


Imperfection: C and C++ need fixed-sized integer types. (p. 195)


Imperfection (reprise): C++ needs fixed sized types that are different to, and not implicitly interconvertible with, its built-in integral types. (p. 196)


Imperfection: C and C++ do not provide large fixed-sized integer types. (p. 200)


Imperfection: bool should be the same size as int. (p. 205)


Imperfection: C and C++ do not provide a dimensionof() operator (for array types). (p. 207)


Imperfection: Inability to distinguish between arrays and pointers can result in static array size determination being applied to pointers or class types, yielding incorrect results. (p. 211)


Imperfection: C and C++ arrays decay into pointers when passed to functions. (p. 214)


Imperfection: C++'s array/pointer duality, combined with its support for polymorphic handling of inherited types, is a hazard against which the compiler provides no assistance. (p. 218)


Imperfection: C++ does not support multi-dimensional arrays. (p. 224)


Imperfection: C++ needs a null keyword, which can be assigned to, and equality compared with, any pointer type, and with no non-pointer types. (p. 229)


Imperfection: Having more than one discrete value for the Boolean type is dangerous. (p. 236)


Imperfection: Specification of the size of integer types as implementation dependent in C/C++ reduces the portability of integer literals. (p. 238)


Imperfection: C++ compilers do not agree on the syntax for suffixes of integer literals larger than those that will fit into (unsigned) long. (p. 239)


Constraint: C and C++ do not guarantee to ensure that identical string literals will be folded within a single link unit, and cannot do so across separate link units. (p. 242)


Constraint: Casting away constness of a constant object is not legal, and will likely lead to unintended consequences. (p. 245)


Constraint: Constants of class type are evaluated as immutable global objects, rather than as compile-time constants. Failure to be mindful of this distinction is hazardous. (p. 246)


Recommendation: Avoid using enum values larger than those that will fit in an int. (p. 248)


Imperfection: C++ does not support member constants of floating-point type. (p. 249)


Constraint: C++ does not support member constants of class type. (p. 250)


Recommendation: Never attempt to simulate class-type member constants with function local static objects. (p. 251)


Imperfection: C++ does not provide access control between types involved in a composition relationship. (p. 257)


Imperfection: The introduction of new keywords into the language requires contingency mechanisms to maintain portability. (p. 268)


Imperfection: Abuse of C++'s last-known access specifier mechanism leads to code that is hard to use and hard to maintain. (p. 271)


Imperfection: Implicitly interpreting non-Boolean (sub-)expressions leads to failure to be mindful of the values of certain types, with a consequent propensity to over-engineer user-defined types. (p. 274)


Imperfection: The implicit interpretation of scalar types as Boolean in conditional statements facilitates erroneous assignment caused by syntax errors. (p. 275)


Imperfection: The contradiction between the old and new for-statement rules results in non-portable code. (p. 278)


Imperfection: for statements requiring initializers of two or more types render the new for-scoping rule irrelevant. (p. 279)


Definition: Conceptual type definitions define logically distinct types. (p. 289)


Definition: Contextual type definitions define types that correspond to well-known concepts, relative to specific contexts. Such types act as descriptions of the nature (type and/or behavior) of their host contexts. (p. 291)


Imperfection: C++ provides no type-safety for the use of conceptual defined types, except where such types have incompatible underlying types. (p. 294)


Imperfection: C++ does not support overloading on conceptually defined types, except where such types happen to have different underlying types on a particular platform. (p. 294)


Recommendation: Avoid making conceptual typedefs that are comprised of contextual typedefs. (p. 304)


Imperfection: Logically related types in C++ can, and usually do, have incompatible interfaces and operations, rendering a generalized approach to type manipulation sometimes difficult, and often impossible. (p. 341)


Definition: Attribute Shims (pp. 343344)

Attribute shims retrieve attributes or states of instances of the types for which they are defined.

The names of attribute shims take the form get_xxx, where xxx represents the particular attribute being accessed (except where they form part of a composite shim concept).

The values returned from attribute shims are always valid outside the instance of the shim, in cases where the shim is implemented by the creation of a temporary object.


Definition: Logical Shims (p. 346)

Logical shims are a refinement of attribute shims in that they report on the state of an instance to which they are applied.

The names of logical shims take the form of an interrogative coupled with the particular attribute or state being queried. Examples would be is_open, has_element, is_null.


Definition: Control Shims (p. 347)

Control shims define operations that are applied to the instances of the types for which they are defined.

The names of control shims take the form of an imperative element coupled with the particular attribute or state being modified. Examples would be make_empty dump_contents.


Definition: Conversion Shims (p. 348)

Conversion shims operate by converting instances of the range of compatible types to a single target type.

The names of attribute shims take the form to_xxx, where xxx is the name of, or represents, the target type, for example, to_int.

The values returned from conversion shims may be provided by intermediate temporary objects, so must only be used from within the expression containing the shim.


Definition: Composite Shims (p. 350)

Composite shims are a combination of two or more fundamental shim concepts.

The names of composite shims do not have a fixed convention, but rather take a name indicative of their purpose.

Composite shims obey the most restrictive rule, or combination of rules, from their constituent shims.


Definition: Access Shims (p. 351)

Access shims are a combination of Attribute and Conversion shims, which are used to access the values of the instances of the types for which they are defined.

The values may have to be synthesised via conversion shims.

The values returned from access shims may be provided by intermediate temporary objects, so must only be used from within the expression containing the shim.


Definition: Veneers (p. 364)

A veneer is a template class with the following characteristics:

  1. It derives, usually publicly, from its primary parameterizing type.

  2. It accommodates, and adheres to, the polymorphic nature of its primary parameterizing type. This means that a veneer cannot define any virtual methods of its own, though it can override those defined by its primary parameterizing type.

  3. It may not define any non-static member variables.

The consequence of 2 & 3 is that a veneer may not change the memory footprint of its primary parameterizing type, and this is achieved by virtue of the Empty Derived Optimization (EDO; see section 12.4), a very widely supported optimization. In other words, instances of a veneer composite have the same size as the primary parameterizing type.


Definition: Bolt-ins (p. 375)

Bolt-ins are template classes with the following characteristics:

  1. They derive, usually publicly, from their primary parameterizing type.

  2. They accommodate the polymorphic nature of their primary parameterizing type. Usually they also adhere to the nature, but this is not always the case, and they may define virtual methods of their own, in addition to overriding those defined by the primary parameterizing type.

  3. They may increase the footprint of the primary parameterizing type by the definition of member variables, virtual functions and additional inheritance from non-empty types.


Imperfection: The C++ template mechanism instantiates a template based on the arguments to it, and takes no account of how, or in what form, those arguments are subsequently used within the templates. This can lead to the generation of inefficient and/or erroneous code since temporary instances of class type may be created during the forwarding of arguments through the template. (p. 387)


Imperfection: Overloading operator &() breaks encapsulation. (p. 425)


Imperfection: Provision of implicit conversion operator(s) to pointer type(s) along with subscript operator(s) is non-portable. (p. 434)


Imperfection: Some C++ compilers will substitute prefix increment/decrement overloaded operators at the call site in place of absent postfix equivalents. (p.440)


Imperfection: Overloading the && and || operators for class types represents an invisible breaking of short-circuit evaluation. (p. 454)


Imperfection: C and C++ make you choose between performance and flexibility when allocating memory. (p. 476)


Imperfection: C/C++ does not support dynamically dimensioned multidimensional arrays. (p. 491)


Recommendation: An array size shim should always be used when determining the sizes of arrays, as all other approaches do not generalize for both built-in and user defined array types. (p. 505)


Imperfection: C++ does not support local functor classes (to be used with template algorithms). (p. 514)


Definition: Type Tunneling is a mechanism whereby two logically related but physically unrelated types can be made to interoperate via the use of Access Shims. The shim allows an external type to be tunnelled through an interface and presented to the internal type in a recognized and compatible form. (p. 518)


Definition: A Range represents a bounded collection of elements, which may be accessed in an incremental fashion. It encapsulates a logical rangethat is, a beginning and an end point, along with rules for how to walk through it (move from the beginning to the end point)and embodies a single entity with which client code may access the values contained within the range. (p. 521522)


Imperfection: C++ does not provide properties. (p. 531)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Please revise the paper:Accurate determination of bathymetric data in the shallow water zone over time and space is of increasing significance for navigation safety, monitoring of sea-level uplift, coastal areas management, and marine transportation. Satellite-derived bathymetry (SDB) is widely accepted as an effective alternative to conventional acoustics measurements over coastal areas with high spatial and temporal resolution combined with extensive repetitive coverage. Numerous empirical SDB approaches in previous works are unsuitable for precision bathymetry mapping in various scenarios, owing to the assumption of homogeneous bottom over the whole region, as well as the limitations of constructing global mapping relationships between water depth and blue-green reflectance takes no account of various confounding factors of radiance attenuation such as turbidity. To address the assumption failure of uniform bottom conditions and imperfect consideration of influence factors on the performance of the SDB model, this work proposes a bottom-type adaptive-based SDB approach (BA-SDB) to obtain accurate depth estimation over different sediments. The bottom type can be adaptively segmented by clustering based on bottom reflectance. For each sediment category, a PSO-LightGBM algorithm for depth derivation considering multiple influencing factors is driven to adaptively select the optimal influence factors and model parameters simultaneously. Water turbidity features beyond the traditional impact factors are incorporated in these regression models. Compared with log-ratio, multi-band and classical machine learning methods, the new approach produced the most accurate results with RMSE value is 0.85 m, in terms of different sediments and water depths combined with in-situ observations of airborne laser bathymetry and multi-beam echo sounder.
02-18

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值