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:
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
38 auto X& operator [] (int i) { return data [i]; }
41 class A_with_ints : A {
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
50 The abstract data member, once realized to a type cannot be changed to
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:
67 virtual const char *typeid;
73 int main (int argc, char **argv)
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)
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
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,
107 In lwc this also works for the structures passed by reference.
108 A better example with complex numbers:
114 complex (float, float);
115 complex &operator = (complex);
116 complex operator + (complex);
123 C1 = complex (1, 2) + complex (1.1, 0) + complex (3.14, 2.74);
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,
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