Rocksolid Light

Welcome to RetroBBS

mail  files  register  newsreader  groups  login

Message-ID:  

Depends on how you define "always". :-) -- Larry Wall in <199710211647.JAA17957@wall.org>


devel / comp.lang.c++ / Re: OOD idea of C++ and class coding guide lines

Re: OOD idea of C++ and class coding guide lines

<5099e453-bf3f-4935-8177-52c7f9978a00n@googlegroups.com>

  copy mid

https://www.rocksolidbbs.com/devel/article-flat.php?id=774&group=comp.lang.c%2B%2B#774

  copy link   Newsgroups: comp.lang.c++
X-Received: by 2002:a05:622a:18a3:b0:3fd:e74b:3194 with SMTP id v35-20020a05622a18a300b003fde74b3194mr37574qtc.2.1688916545209;
Sun, 09 Jul 2023 08:29:05 -0700 (PDT)
X-Received: by 2002:a65:6a84:0:b0:55b:1e0e:d278 with SMTP id
q4-20020a656a84000000b0055b1e0ed278mr7254248pgu.1.1688916544571; Sun, 09 Jul
2023 08:29:04 -0700 (PDT)
Path: i2pn2.org!i2pn.org!usenet.blueworldhosting.com!diablo1.usenet.blueworldhosting.com!peer01.iad!feed-me.highwinds-media.com!news.highwinds-media.com!news-out.google.com!nntp.google.com!postnews.google.com!google-groups.googlegroups.com!not-for-mail
Newsgroups: comp.lang.c++
Date: Sun, 9 Jul 2023 08:29:03 -0700 (PDT)
In-Reply-To: <d7797b83-4c9f-422a-b1e4-ab7ac5151782n@googlegroups.com>
Injection-Info: google-groups.googlegroups.com; posting-host=124.218.76.41; posting-account=0Ek0TQoAAAAS0oceh95IuNV59QuIWNeN
NNTP-Posting-Host: 124.218.76.41
References: <4ebc633e-2dbd-4c5d-b9d1-45101d781c4dn@googlegroups.com>
<fc5bec45-71f3-47f1-964e-d90d8ca8bbf5n@googlegroups.com> <d7797b83-4c9f-422a-b1e4-ab7ac5151782n@googlegroups.com>
User-Agent: G2/1.0
MIME-Version: 1.0
Message-ID: <5099e453-bf3f-4935-8177-52c7f9978a00n@googlegroups.com>
Subject: Re: OOD idea of C++ and class coding guide lines
From: wyniijj5@gmail.com (wij)
Injection-Date: Sun, 09 Jul 2023 15:29:05 +0000
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
X-Received-Bytes: 11483
 by: wij - Sun, 9 Jul 2023 15:29 UTC

On Tuesday, July 4, 2023 at 12:32:17 AM UTC+8, wij wrote:
> The following is the updated guideline (file ClassGuideLines.txt), posted for
> review. Subtleness is there, don't be fooled by simplicity.
>
> ----- ClassGuideLines.txt
>
> This file updates the class guideline in Rationale.txt
> The guideline focuses on the OO way of class (concept) design, and is made to
> ensure that the class (concept) design is provably consistent.
>
> +----------------------------------------------------------+
> | Sequence of acquisition incident: Object life cycle view |
> +----------------------------------------------------------+
> 1. Name binding
> (there might be anonymous object)
> 2. Size binding
> Information to allocate memory
> 3. Address binding
> Object in this stage is called in random state.
> 4. Semantics binding
> Object is in responsible state of the occupied space and contents.
> (external resource may be associated in the semantics)
> 5. Reversal is the object destruct process
>
> Note: Class of objects whose destructor can be runtime ignored is referred
> to as discardable in this library. Often, such class has no user
> defined destructor and such objects can be overwritten.
>
> ----Result of the life cycle view is the basic rule of class members
> Constructor(..):
> Constructor forms are in basic the Cartesian product view of problem domain
> in tupple. IOW, the class (concept) is defined by the arguments of ctor.
> Constructor brings an object in random state to responsible state.
>
> Destructor:
> The destructed object is no longer considered existing in the C++ language
> (ref. [12.4.14]). Since destructing an object the second time results to
> undefined behavior, destructor must make sure destructing it once is enough.
> In another word, destructor must succeed to the language. Object destruction
> actually magnifies the effect of common ignorance of the implicitly created
> rollback function (or a design).... The program execution from return/throw/
> exit.. to its caller(e.g. main, init..) shall succeed.
> Note: C++ language had enforced the semantics that 'destructor must succeed'.
>
> const member functions:
> Const members define the property of the class. Normally, these 'property'
> members should be in O(1) complexity. If properties of two objects are equal,
> the objects should behave the same.
> These members provide the basic proofs that the class is properly designed.
> Reset(..) members:
> Reset members brings the object from responsible state back to random state
> and then does whatever the argument corresponding constructor does.
> Therefore, If a reset member exists then the argument(s) corresponding
> constructor also exists.
>
> Construct/destruct/reset are implemented as composite operations of object
> initialization process of the life cycle view (and the symmetrical reverse).
> Implementation can optimize the theoretical sequence.
>
> Since this library adopts an implicit rule that object has to be in a 'valid'
> state (no good in class like Array), the reset() postcondition is thus
> required to be default. Default state is among the easiest check points to
> ensure object constructed, in whatever valid state, can always be
> successfully destructed. Note that reset members normally exist but not
> necessary. For instance, if the class contains const or reference data
> members, then the reset would be difficult to implement.
>
> Move Constructor:
> The motivation of devising is from the need to avoid costly and unnecessary
> copy operations found in classes that contain allocated resources and the
> objects movement in a dynamic array. It has been practiced that such
> motivation basically just need a *move constructor*. This library uses
> "enum ByMove_t { ByMove }" as the signature denoting a move constructor (for
> the moment), which is defined to move the source referenced object to 'this'
> pointed address (source object is treated non-existent). The reason is that
> such an operation is conceptually elementary, thus, it can enable the
> definition of a no-throw swap function template (note: implementation needs
> a buffer type, e.g. type_store<T>, but this is a different issue).
>
> Many other libraries do not contain the move constructor. Bit-wise copy
> (memcpy) may mostly do the job, e.g. QString of Qt library, so far. Just
> make sure that destructor of the moved object won't be called.
>
> Note: C++11 introduced rv-reference and defined another name 'std::move',
> a constructor taking a rv-reference argument is therefore called a move
> constructor. This library decided to continue the development using this now
> standard-confusing move constructor. Simply because ByMove is relatively
> more elementary. Many reasons can eventually be translated to being light
> weight, which in a way means it can transform easier. Again, This library's
> guide "No room should be left for lower-level implement". Another reason is
> the ratio of gain vs. cost does not appear good for the author to use it,
> hopefully this library can survive.
>
> -------- Class member rules
> The general rule: Class members should be able to conduct self-check for
> correctness, except not possible.
> Let T denote a given class of this library. The following member names
> and associated functionality are defined.
>
> T() Default constructor. The object thus construted is referred
> to as in default state and so the default object.
>
> Postcondition of throw: object does not exist.
>
> Note: If object can mean 'no real contents', the default object is
> better thus designed, at least to be safely destructable.
> T(const T&) Construct *this to the state as the source object.
> (nothing more to say from general practice)
> T(T&, ByMove_t) Move the source object to 'this' pointed address.
> This member is not really a constructor since nothing is created.
>
> Errno reset(...)
> Reconstruct the object to the state as constructed by the arguments
> corresponding constructor.
>
> Ex: reset members should ideally function identical to the following
> example:
> Errno T::reset(Type1 a, Type2 b) try {
> T obj(a,b);
> swap(*this,obj);
> return Ok;
> }
> catch(const Errno& e) {
> return e;
> };
>
> Note: This rule is important. Real practice may want do things
> slightly different in some cases, but no. Hidden and hard to
> find bugs may exist (maybe the concept or interface of the
> class design should be reconsidered).
> Note: For reset() (no argument), object return (and Reply) state is
> always default regardless of the Errno, if exists, returned.
> ~T Destruct object
>
> Postcondition: object does not exist
>
> bool is_default() const
> return true iff object is equivalent to the default constructed
> object (i.e a.is_default() <==> a==T(), if operator== is defined).
>
> bool operator==(const T& rhs) const
> This function returns true iff *this and rhs are not distinguishable
> by using any non-private member on the same condition unless
> otherwise explicitly specified.
>
> Note: Object equivalence does not include equivalence of SLI and
> address of its own.
>
> T& operator=(const T&)
> Reconstruct object to the state as the copy constructor constructed
> (same as reset(const T&) except the return type and throwing error).
>
> void swap(&T)
> Exchange object state of *this and the argument indicated object.
>
> Take 'a.swap(b)' (commutative) for instance, the state of a is set
> to the state of b. The previous state of a becomes the state of b.
> The same applies for b
> Note: No construct and destruct semantics is involved
>
> Reply
> Class specific throw class inheriting Errno.
>
> _.. prefix for system-specific members or candidate, or restricted..etc.
>
> wy_.. prefix for internal members (for testing, etc.).
>
> ------

A section about throwing error is added to libwy guidelines, posted for review.

-------- Throwing error
As an elementary library, libwy has to make any error report of provided
functions be able properly handled by its caller to accomplish the function
requested and don't create exception.
Throwing error loses the context information. FUNCTIONS (and ctor/dtor/..) SHOULD
CATCH ALL CONFUSING ERRORS THROWN TO CONVERT TO THE ONE IT IS RESPONSIBLE.
Difficulty exists to achieve this requirement especially for template classes,
therefore, libwy should minimize using template in general (Array<T> seems to
defy this rule...).

Note: Implement should also consider other things like thread cancellation and
signal-safety.

+--------------------------+
| Appendix: Losing Context |
+--------------------------+
The error thrown may not associate to the function being called.

int read_integer(size_t maxlen) {
int v;
if(maxlen>10) {
throw Invalid_Argument;
}
// read string and convert to integer (Invalid_Argument may be thrown)
return v;
}

void f(int count) {
int v;
if(count<0) {
throw Invalid_Argument;
}
for(int i=0; i<count; ++i) {
try {
v= read_integer(8);
}
catch (Invalid_Argument) {
// May not be the Invalid_Argument in read_integer(..) thrown.
// Decisions based on this assumption will be wrong.
}
}
}

The Invalid_Argument caught in f may not mean the argument of read_integer(...)
is invalid. Likewise, if Invalid_Argument is rethrown or passed, it does not
necessarily mean the argument 'count' of f is invalid.
-----------

SubjectRepliesAuthor
o OOD idea of C++ and class coding guide lines

By: wij on Wed, 28 Jun 2023

15wij
server_pubkey.txt

rocksolid light 0.9.81
clearnet tor