added UGLY hacks to compile regexp code (look for 'k8:hack')
[k8-lwc.git] / doc / 9.0.new-in-1.3
blobafc1cac5767f96100f14ad01462f8adcbb9943cb
2 1. Cost-free unwind
3 ~~~~~~~~~~~~~~~~~~~
4  In order to call the destructors of local objects when exceptions
5 are raised, without any performance cost, we need serious help from
6 the C compiler.  gcc-3.4 offers such a feature.
8  If lwc is compiled with gcc 3.4 and above the cost-free exceptions
9 are enabled by default.  This feature can also be enabled or disabled
10 at lwc-runtime with the lwc_config options:
12         // in a global header
14         _lwc_config_ { gcc34cleanup; }          // enable
15         _lwc_config_ { no_gcc34cleanup; }       // disable
17  If you are interested in using lwc's try-throw then in this case the
18 generated C code must be compiled with '-fexceptions'.  Otherwise lwc
19 has arranged for a segmentation violation to happen when you throw.
21  In the case of gcc34 cleanups, ALL local objects are automatically
22 destructed when exceptions are raised.  The keyword __unwind__ is
23 redundant but causes no error when used.
25  gcc34 cleanups through exceptions may not work with NPTL's
26 cancellations. generally, it's wrong terminating threads with longjmps
27 and gcc's _Unwind mechanisms belong to the lwc preprocessor!
30 2. Pure class-typedefs and abstract data members
31 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
32  That's the feature from the previous version's wishlist. Example of
33 generic object:
35         class A {
36         typedef X = 0;
37                 X data [100];
38         auto    X& operator [] (int i)  { return data [i]; }
39         };
41         class A_with_ints : A {
42         typedef int X;
43         };
45  Only auto-functions can use abstract data members like 'data'. This member
46 is really created in 'A_with_ints'. It is possible to have instances of 'A'
47 but the auto functions that use pure typedefs or abstract data members do
48 not exist.
50 The abstract data member, once realized to a type cannot be changed to
51 another type.
53 That's an alternative way to achieve generic programming and the philosophy
54 is different.  For a generic container of containers we need forward
55 specializations a-la hierarchy stuff.
58 3. automatic typeid generation
59 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
60  'typeid' can be the name of a special virtual variable. lwc automatically
61 initializes this virtual variable with a pointer to a string which is the
62 stringified name of the class.  This can be used to report the type of an
63 instance but also compare instances for the same type and even get to
64 mutliple-dispatch scenarios.  For example:
66         class A {
67         virtual const char *typeid;
68         };
70         class B : A {
71         };
73         int main (int argc, char **argv)
74         {
75                 // prints "A B"
76                 printf ("%s %s\n", A.typeid, B.typeid);
78                 A *ap = (argc > 2) ? new A : new B;
79                 printf ("ap is of type %s\n", ap->typeid);
81                 // multiple dispatch howto
82                 if (ap->typeid == A.typeid)
83                         printf ("A");
84         }
86 For the last check, theoretically, it might be safer to strcmp() the typeids.
87 However in small programs we may be able to just compare the addresses of the
88 strings.
91 4. Object Declaration Expressions
92 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
93  That is a feature present in C++ and it is when an anonymous object
94 declaration can be used in expressions.  For example,
96         class A {
97                 A () {}
98         };
100         int f (A);
102         int main ()
103         {
104                 f (A ());
105         }
107 In lwc this also works for the structures passed by reference.
108 A better example with complex numbers:
110         class complex
111         {
112                 float re, im;
113                 complex ();
114                 complex (float, float);
115                 complex &operator = (complex);
116                 complex operator + (complex);
117         };
119         int f ()
120         {
121                 complex C1;
123                 C1 = complex (1, 2) + complex (1.1, 0) + complex (3.14, 2.74);
124         }
126 Lifetime of the temporary object:
127 **The temporary object is constructed before the expression and destructed
128  after it. The exceptions to this are cases where expressions may not be
129  evaluated and they are '?:' '&&' and '||' and 'sizeof'. In the conditional,
130  we can't say
132         foo (x ? A () : B ());
134  because we want to construct only one of A and B and therefore we'd have to
135  implement a second conditional after foo() to destruct only one. Not
136  implemented.