220 37355 <1c12a5bb-154e-431e-a064-73f2d3a8af9e@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: emuzychenko@gmail.com
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Custom inheritable data/function attributes (for
 example, for multi-threaded or real-time code)
Date: Fri, 16 Mar 2018 03:03:01 -0700 (PDT)
Lines: 269
Approved: news@gmane.org
Message-ID: <1c12a5bb-154e-431e-a064-73f2d3a8af9e@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_686_70232112.1521194581856"
X-Trace: blaine.gmane.org 1521194462 21102 195.159.176.226 (16 Mar 2018 10:01:02 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Fri, 16 Mar 2018 10:01:02 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDMKDQOIY4JBBVVMV3KQKGQE3RTFINI@isocpp.org Fri Mar 16 11:00:58 2018
Return-path: <std-proposals+bncBDMKDQOIY4JBBVVMV3KQKGQE3RTFINI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-vk0-f71.google.com ([209.85.213.71])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDMKDQOIY4JBBVVMV3KQKGQE3RTFINI@isocpp.org>)
	id 1ewmAS-0005Lq-U9
	for gclcip-std-proposals@m.gmane.org; Fri, 16 Mar 2018 11:00:57 +0100
Original-Received: by mail-vk0-f71.google.com with SMTP id n23sf6130460vke.14
        for <gclcip-std-proposals@m.gmane.org>; Fri, 16 Mar 2018 03:03:04 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=uXrDVAoet6y2xxDt6iLAXxvg3IjC3J1gv4xmiV4sUXA=;
        b=lAB7W5tRkcDNEYIR3mlaWw0a1zJHgCgT+rGVwWKW62AZAz4Ko8KmPANe8tTyk3DIQx
         szN8iGKaKXI4mhNyJWj0f5gLXTp0ht+RnrTawmRiCsG+jrF10O35fLKVuytbmvrpn8hT
         nrf7VC88321x/t8a5eL6O16qRRNWhxLlAk+0TP3yEn/aFnzJQLpIZsTu+qNLjX5fglYN
         ZPQK0o1tmjOVgoU6BXwEzxT6fj/75j3YpYf7HaiI2/EgOfH/rvvz2pyqkrRQMU3RuL1I
         3JdkJs5dCJ9xOvG33QAdGS9tokB+Rrstu68x8M9MpqA4HpxAdkpd1e0gzYgkWkWzfISb
         9iNg==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=uXrDVAoet6y2xxDt6iLAXxvg3IjC3J1gv4xmiV4sUXA=;
        b=Gfeot9URUcCPwqg3jOPcbFAQv4i9L0O2Cz2N+ZyHppWCo4Alvw1a9aSUtVrXk8Qmmn
         T+AjqCYhk4tBsPCEfH+LIgbC0lAD8h972D3JNsLZZRYkHdRgmTk9DhC3LlH+u2oLzedO
         xCvlNchkgqvrLor4zoZYddEuZNg3KSOo+rfFO/8CNH1/AGKSEYppv5UMRB+lUqMEpQTJ
         dC9HeqXcwaDir0IKiGVxP8/jnW8DZfcQbXLkYwR+zyCPklmnoe0qiBdRkNyfmHsiXR5B
         Y8q8e3lXA19WoVv/6XwKksB0njtWMT1dbtv1fBNEoScbAMbfvD5rso13IvAvErWl4ZlL
         Sbcg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=uXrDVAoet6y2xxDt6iLAXxvg3IjC3J1gv4xmiV4sUXA=;
        b=m0Fc3bkUctS65GZpA4swC5Un6BLpBMmdICZkUpR9jm6zxKQmlkS+IubwB4M0+5xtnX
         jWiIVV0uzmOyKA4tzvahYIzrIpw6cicfPkIM2y8I7ObzAsufT9ym4LCNWPNijnrM7jHI
         dtjn8rstx3MVdhIsrVVQlr5q90XCuUc5EvW66vhGVtt7iZPQZ913Tb1tDEbbwoR831s7
         fChTT5R7n2Iq2AfTv+rA85ig3a6MCSv+N1OKHOOVvGhdqJFOD6A2qV8RteOXNn994VNx
         IsONBGY0Rh6Ccrj4ay+cbwVNepZA+GnHsQNNPcOuW2bjAp/kSjeU/lGa+NhwCwmLBzJA
         5eGQ==
X-Gm-Message-State: AElRT7E9cpW1C6weogRfbRA6VZyqXio7wNvNXLbNx+A1xiZuiS/z6xMr
	RUiymp9YTelYDQrfCuO/RT4Kcg==
X-Google-Smtp-Source: AG47ELuj7hiTxZo42X3b19NSnaKQ92NLXPVxV/U5c4gTDnsmquleq4k2eq9IwYjOTJgDEIQ4zzNaMA==
X-Received: by 10.31.170.81 with SMTP id t78mr472578vke.81.1521194583864;
        Fri, 16 Mar 2018 03:03:03 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.31.208.1 with SMTP id h1ls3698526vkg.19.gmail; Fri, 16 Mar
 2018 03:03:02 -0700 (PDT)
X-Received: by 10.31.149.199 with SMTP id x190mr149731vkd.11.1521194582349;
        Fri, 16 Mar 2018 03:03:02 -0700 (PDT)
X-Original-Sender: emuzychenko@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:37355
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/37355>

------=_Part_686_70232112.1521194581856
Content-Type: multipart/alternative; 
	boundary="----=_Part_687_1893615824.1521194581856"

------=_Part_687_1893615824.1521194581856
Content-Type: text/plain; charset="UTF-8"

C++ supports very useful *const* attribute. It can be assigned to both data 
and code (function). It is *inheritable* ('const' member of a base class is 
still constant in derived classes, 'const' member function gets a 'const' 
object). There is less useful *volatile* attribute, working the same way.

I think it is a good idea to have an ability to declare custom 
(user-defined) *compile-time-only* attributes that can be assigned either 
(or both) to data and/or code, make them inheritable, and define some usage 
restrictions, like const/volatile do.

Example 1: in a parallel <https://en.wikipedia.org/wiki/Parallel_computing> 
(multi-threaded) code with concurrent data access, an object can be shared 
between several threads. To access the object safely, a thread must ensure mutual 
exclusion <https://en.wikipedia.org/wiki/Mutual_exclusion> with other 
threads, acquiring a *lock* (a mutex, semaphore, critical section etc.) 
associated with the object. There are no problems accessing a single shared 
object at a time. But if a thread needs to access several shared objects, 
each of them protected with its own lock, a deadlock 
<https://en.wikipedia.org/wiki/Deadlock> can occur. In spite of there is an 
explicit association between the object and the protection lock, there is 
no language feature to declare this association at compile time. So many 
errors that may cause deadlocks are found at run-time only. There are 
complex software instruments to analyze run-time code behavior while the 
same work can easily be performed by a compiler at compile time.

Example 2: real-time <https://en.wikipedia.org/wiki/Real-time_computing> 
programming (including embedded system programming). There is an important 
code/data property like "can cause a long delay". It may be a code executed 
too long, or accesses resources not available "momentarily" (disk or even 
network files), or acquiring a protective lock for shared access; a data 
that can be protected by a lock, or paged 
<https://en.wikipedia.org/wiki/Paging> out, or need to be built. To avoid 
undesired execution delays, or blocking 
<https://en.wikipedia.org/wiki/Blocking_(computing)>, a real-time process 
must not call such code or access such data. But there are no language 
features to declare/check such code/data properties so many errors are very 
hard to find.

Example 3: kernel-mode programming. OS kernels have some data objects that 
can be accessed (or functions can be called) only with specified conditions 
(for example, cannot be accessed/called from an interrupt handler). Errors 
related to violation of such rules can be found only at run time.

Example 4: there can be "reliable" (checking all their arguments on every 
call) and "unreliable" (relying on the caller) functions. Of course, a 
reliable function can call either reliable or unreliable function but 
unreliable function should not call another unreliable one.

All these code/data properties are *inheritable* by their nature:

   - If a class requires mutual exclusion to access its objects, all 
   classes derived from (or including) this class may require it too (a 
   'data-to-data' inheritance).
   - If a function can block 
   <https://en.wikipedia.org/wiki/Blocking_(computing)> thread execution, 
   all functions calling this function can block too (a 'code-to-code' 
   inheritance).
   - If a function accesses an object protected by a lock, this function 
   can block thread execution (a 'data-to-code' inheritance).
   - If a class has member functions than can block, access to class 
   objects can block too (a 'code-to-data' inheritance).
   
The proposal is to add language features allowing to declare and check 
various code/data attributes.

For such idea, there should be three features:

   - Attribute declaration, separate for code and data
   - Attribute inheritance rules
   - Attribute checking rules
   
Attributes used in a program can be (but not obligatory) declared in 
advance:

attributes {
  data:needs_lock_a, // Accessing code must hold mutex (lock) A
  data:needs_lock_b, // Accessing code must hold mutex (lock) B
  code:needs_lock_a, // Needs mutex (lock) A to be held by a caller
  code:needs_lock_b, // Needs mutex (lock) B to be held by a caller
  code:holds_lock_a, // Holds mutex (lock) A
  code:holds_lock_b, // Holds mutex (lock) B
  code:can_block, // Can block execution flow
  code:realtime, // Real-time code that cannot be blocked
  data:pageable, // Occupies non-locked memory that can be paged out
}

class attribute (cannot_be_accessed_from_interrupt_handler) 
ResourceDescriptor {...};
int attribute (needs_lock_a) Count1;
int attribute (needs_lock_b) Count2;
void attribute (holds_lock_a) IncreaseCounter1 ();
void attribute (holds_lock_b) IncreaseCounter2 ();

Therefore, attribute type (data/code) can be derived implicitly from the 
declaration/definition.

Inheritance rules should define the following:

   - If an object is wrapped with another object, all data attributes are 
   inherited.
   - If a function calls (explicitly) another function, the caller function 
   inherits all callee code attributes.
   - If a function accesses an object, how code attributes are derived from 
   data attributes.
   - If a class has a member function, object data attributes are derived 
   from function code attributes.
   
attribute_inheritance (<source>, <destination>)

attribute_inheritance (data:needs_lock_a, code:needs_lock_a) // Code 
accessing the object must host lock A
attribute_inheritance (data:needs_lock_b, code:needs_lock_b) // Code 
accessing the object must host lock B
attribute_inheritance (code:holds_lock_a || holds_lock_b, code:can_block) 
// Code holding a lock can block the execution
attribute_inheritance (data:pageable, code:can_block) // Code accessing 
pageable data can block the execution

Checking rules (assume that attribute names return boolean values):

attribute_check (code:realtime != code:can_block) // Realtime code is not 
compatible with blocking code
attribute_check (!(code:holds_lock_b && code_needs_lock_a)) // If a code 
holds lock B, it cannot hold lock A (prevent deadlocks)

Or there could be an operator like "get_attribute ()", returning attributes 
of a class, object or function, to be used in a statement like assume().

Keywords and syntax used are for example only, actual implementation could 
be completely different.

Such access control model can be used to implement various access rules 
(for example, in cases where "mutable" cannot be used safely, or to mark 
test/unfinished objects/functions that must not be accessed by production 
code).

-- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/1c12a5bb-154e-431e-a064-73f2d3a8af9e%40isocpp.org.

------=_Part_687_1893615824.1521194581856
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">C++ supports very useful <b>const</b>  attribute. It can b=
e assigned to both data and code (function). It is <b>inheritable</b> (&#39=
;const&#39; member of a base class is still constant in derived classes, &#=
39;const&#39; member function gets a &#39;const&#39; object). There is less=
 useful <b>volatile</b> attribute, working the same way.<br><br>I think it =
is a good idea to have an ability to declare custom (user-defined) <b>compi=
le-time-only</b> attributes that can be assigned either (or both) to data a=
nd/or code, make them inheritable, and define some usage restrictions, like=
 const/volatile do.<br><br>Example 1: in a <a href=3D"https://en.wikipedia.=
org/wiki/Parallel_computing">parallel</a> (multi-threaded) code with concur=
rent data access, an object can be shared between several threads. To acces=
s the object safely, a thread must ensure <a href=3D"https://en.wikipedia.o=
rg/wiki/Mutual_exclusion">mutual exclusion</a> with other threads, acquirin=
g a <b>lock</b> (a mutex, semaphore, critical section etc.) associated with=
 the object. There are no problems accessing a single shared object at a ti=
me. But if a thread needs to access several shared objects, each of them pr=
otected with its own lock, a <a href=3D"https://en.wikipedia.org/wiki/Deadl=
ock">deadlock</a> can occur. In spite of there is an explicit association b=
etween the object and the protection lock, there is no language feature to =
declare this association at compile time. So many errors that may cause dea=
dlocks are found at run-time only. There are complex software instruments t=
o analyze run-time code behavior while the same work can easily be performe=
d by a compiler at compile time.<br><br>Example 2: <a href=3D"https://en.wi=
kipedia.org/wiki/Real-time_computing">real-time</a> programming (including =
embedded system programming). There is an important code/data property like=
 &quot;can cause a long delay&quot;. It may be a code executed too long, or=
 accesses resources not available &quot;momentarily&quot; (disk or even net=
work files), or acquiring a protective lock for shared access; a data that =
can be protected by a lock, or <a href=3D"https://en.wikipedia.org/wiki/Pag=
ing">paged</a> out, or need to be built. To avoid undesired execution delay=
s, or <a href=3D"https://en.wikipedia.org/wiki/Blocking_(computing)">blocki=
ng</a>, a real-time process must not call such code or access such data. Bu=
t there are no language features to declare/check such code/data properties=
 so many errors are very hard to find.<br><br>Example 3: kernel-mode progra=
mming. OS kernels have some data objects that can be accessed (or functions=
 can be called) only with specified conditions (for example, cannot be acce=
ssed/called from an interrupt handler). Errors related to violation of such=
 rules can be found only at run time.<br><br>Example 4: there can be &quot;=
reliable&quot; (checking all their arguments on every call) and &quot;unrel=
iable&quot; (relying on the caller) functions. Of course, a reliable functi=
on can call either reliable or unreliable function but unreliable function =
should not call another unreliable one.<br><br>All these code/data properti=
es are <b>inheritable</b> by their nature:<br><ul><li>If a class requires m=
utual exclusion to access its objects, all classes derived from (or includi=
ng) this class may require it too (a &#39;data-to-data&#39; inheritance).</=
li><li>If a function can <a href=3D"https://en.wikipedia.org/wiki/Blocking_=
(computing)">block</a> thread execution, all functions calling this functio=
n can block too (a &#39;code-to-code&#39; inheritance).</li><li>If a functi=
on accesses an object protected by a lock, this function can block thread e=
xecution (a &#39;data-to-code&#39; inheritance).</li><li>If a class has mem=
ber functions than can block, access to class objects can block too (a &#39=
;code-to-data&#39; inheritance).<br></li></ul>The proposal is to add langua=
ge features allowing to declare and check various code/data attributes.<br>=
<br>For such idea, there should be three features:<br><ul><li>Attribute dec=
laration, separate for code and data</li><li>Attribute inheritance rules</l=
i><li>Attribute checking rules<br></li></ul>Attributes used in a program ca=
n be (but not obligatory) declared in advance:<br><br>attributes {<br>=C2=
=A0 data:needs_lock_a, // Accessing code must hold mutex (lock) A<br>=C2=A0=
 data:needs_lock_b, // Accessing code must hold mutex (lock) B<br>=C2=A0 co=
de:needs_lock_a, // Needs mutex (lock) A to be held by a caller<br>=C2=A0 c=
ode:needs_lock_b, // Needs mutex (lock) B to be held by a caller<br>=C2=A0 =
code:holds_lock_a, // Holds mutex (lock) A<br>=C2=A0 code:holds_lock_b, // =
Holds mutex (lock) B<br>=C2=A0 code:can_block, // Can block execution flow<=
br>=C2=A0 code:realtime, // Real-time code that cannot be blocked<br>=C2=A0=
 data:pageable, // Occupies non-locked memory that can be paged out<br>}<br=
><br>class attribute (cannot_be_accessed_from_interrupt_handler) ResourceDe=
scriptor {...};<br>int attribute (needs_lock_a) Count1;<br>int attribute (n=
eeds_lock_b) Count2;<br>void attribute (holds_lock_a) IncreaseCounter1 ();<=
br>void attribute (holds_lock_b) IncreaseCounter2 ();<br><br>Therefore, att=
ribute type (data/code) can be derived implicitly from the declaration/defi=
nition.<br><br>Inheritance rules should define the following:<br><ul><li>If=
 an object is wrapped with another object, all data attributes are inherite=
d.<br></li><li>If a function calls (explicitly) another function, the calle=
r function inherits all callee code attributes.<br></li><li>If a function a=
ccesses an object, how code attributes are derived from data attributes.</l=
i><li>If a class has a member function, object data attributes are derived =
from function code attributes.<br></li></ul>attribute_inheritance (&lt;sour=
ce&gt;, &lt;destination&gt;)<br><br>attribute_inheritance (data:needs_lock_=
a, code:needs_lock_a) // Code accessing the object must host lock A<br>attr=
ibute_inheritance (data:needs_lock_b, code:needs_lock_b) // Code accessing =
the object must host lock B<br>attribute_inheritance (code:holds_lock_a || =
holds_lock_b, code:can_block) // Code holding a lock can block the executio=
n<br>attribute_inheritance (data:pageable, code:can_block) // Code accessin=
g pageable data can block the execution<br><br>Checking rules (assume that =
attribute names return boolean values):<br><br>attribute_check (code:realti=
me !=3D code:can_block) // Realtime code is not compatible with blocking co=
de<br>attribute_check (!(code:holds_lock_b &amp;&amp; code_needs_lock_a)) /=
/ If a code holds lock B, it cannot hold lock A (prevent deadlocks)<br><br>=
Or there could be an operator like &quot;get_attribute ()&quot;, returning =
attributes of a class, object or function, to be used in a statement like a=
ssume().<br><br>Keywords and syntax used are for example only, actual imple=
mentation could be completely different.<br><br>Such access control model c=
an be used to implement various access rules (for example, in cases where &=
quot;mutable&quot; cannot be used safely, or to mark test/unfinished object=
s/functions that must not be accessed by production code).<br></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/1c12a5bb-154e-431e-a064-73f2d3a8af9e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/1c12a5bb-154e-431e-a064-73f2d3a8af9e=
%40isocpp.org</a>.<br />

------=_Part_687_1893615824.1521194581856--

------=_Part_686_70232112.1521194581856--

.
