Topic: [C++0x] Qualifiers, more qualifiers, aspects and annotations, oh


Author: f5xz2bk02@sneakemail.com (Davide Bolcioni)
Date: Mon, 25 Oct 2004 18:21:55 GMT
Raw View
Greetings,
reading recent papers for the core language, such as n1706, n1703 and
n1696, a thought occurred to me: all introduce declarative meta
information about the relevant entities. In the Java camp, the
syntactic concept of "annotations" has been introduced which seems to
subsume all of the above nicely, and I was wondering if it could be
borrowed somehow to provide an unified syntactic approach which frees
C++ from the "cannot define appropriate keyword" syndrome, but also
from a deluge of keywords and qualifiers (which to some extent already
occurs in Java).

The following are just stabs at a proposed variant syntax for a
number of concepts picked from recent papers in no particular order;
note that often I only show the *declaration* of annotations because
I have no idea of what the definition should be :-).

Although I cannot tell what exactly an annotation in C++ is supposed
to be, it seems to me that annotations:
- should be namespaced, with standard annotations defined in std::
   and possibly compiler specific annotations (see [1] below);
- could be intrinsic, meaning known and acted upon by the compiler,
   but if not intrinsic a definition must be available;
- could result from template instantiation, i.e. I can introduce
   template annotations with type and non-type parameters;
- should be found using lookup rules as similar as possible to the
   lookup rules applicable to the entities they annotate, because C++
   has enough lookup rules as it stands;
- should behave mostly like classes, e.g. allowing single inheritance
   (maybe multiple, no clue about non-public inheritance).

Annotation syntax consists of a comma separated list of annotation
expressions between square brackets, as shown in the examples below.

Example 1: declaring annotations

   namespace my_namespace {
     class [std::annotation] my_annotation;
     class [std::annotation] my_other_annotation: public my_annotation;
     template <class T> class [std::annotation] my_templated_annotation;
   }

i.e. to declare an annotation I declare a class annotated as an
annotation. Instantiating a template can generate an annotation.

Example 2: annotating classes

   using my_namespace::my_annotation;
   class [my_annotation] my_class;

Example 3: annotating typedefs (n1706)

   typedef [std::derived] unsigned int game_score; // n1706 public
   typedef [std::separate] unsigned int id; // n1706 private

Example 4: annotating functions (n1703)

   explicit [std::pure, std::nothrow] void f();

Example 5: arbitrary user defined annotations (off the top of my head)

   class [std::annotation] my_qualifier: public std::method_qualifier { }
   struct my_class { explict [my_qualifier] void g(); }
   my_class c1; // g.f() is error
   explicit [my_qualifier] my_class c2; // g.f() is OK

Introduces my_qualifier as a member qualifier, which behaves essentially
like const qualification with respect to method invocation only, and
seems to me a good use for supporting inheritance of annotations and
Liskov substitution.

Note the abuse of "explict" where C++ syntax does not easily bend to
allow a bracketed list; you can read that as "declare", it applies the
listed annotations to the entity being declared.

Example 6: class annotations (n1702)

   class [std::no_default_constructor, std::default_destructor] example;
   class [std::no_default_methods] another_example;
   class [std::annotation] my_default_methods_policy: public
      std::no_default_constructor, std::default_copy_constructor,
      std::default_destructor { }

This might be construed as a use case for multiple inheritance of
annotations.

Example 7: restricted templates (n1696 and others)

   template [std::unrestricted] <class C>
     struct [std::restrict<C()>] class copy;

   template [std::restricted] <class V>
     struct [std::restrict<is_integral<V>::value>] class hash;

Here I whipped up a combination of predefined annotations, but I should
probably read n1696 and related papers more carefully: std::restricted
indicates that this template or specialization is considered only if all
instantiations of std::restrict<> succeed, while std::unrestricted is
always applicable and requires a diagnostic if any instantiation fails.

This posting is long enough, so I will not be more exhaustive than this;
I just wanted to feel the waters about this idea. I believe that aspect
oriented programming, design by contract and shared library support
could all be expressed using annotations. Or coerced into.

[1] Compiler specific annotations, if allowed, seem likely to introduce
portability problems. At first glance we might:
- allow intrinsic annotations only inside the std:: namespace and
   namespaces inside the std:: namespace;
- require that compiler specific annotations be defined in
   std::compiler::<name>, where <name> is a vendor-picked name for the
   compiler - compatible compilers can support more than their own;
- maybe a namespace is a bad choice, I am not sure there are ways to
   switch at compile time on a namespace being present;
- big unsolved problem: if we manage to get e.g. C++/CLI expressed using
   annotations, what should happen if we compile the code on a non-CLI
   aware compiler ?

Davide Bolcioni

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]