Note for IBM OS/390 C++ users

------------------------------------------------------------------------

Known Problems

Compiling:

  1. OS/390 C/C++ requires explicit template notation such as
     template_class<Param> where most other conformant compilers only
     accept template_class (inside template method bodies, etc.):

       template <class Param> class template_class {

         template_class foo();            // error for OS390 C/C++

         template_class<Param> foo();     // OK

         ...

       };

     This adaptation works around the above OS/390 C/C++ requirement, but
     may cause compatibility problems when porting template code from other
     platforms.

  2. OS/390 C++, does not allow passing an extern "C" function pointer as
     an argument to a C++ function. For example:

       template <class Result>

           pointer_to_void_function<Result> ptr_gen(Result (*x)());



       p = ptr_gen(rand);   // error for OS/390 C/C++

     In the above template, ptr_gen takes a function pointer as its
     argument and returns a function pointer adaptor (a type of function
     object), and rand is an extern "C" library pointer. This is not
     allowed because C and C++ linkage is different on OS/390 C/C++.

     To work around this problem, provide a C++ wrapper around the extern
     "C" function and pass the C++ wrapper instead:

       int cxxrand(void) { return rand();}

       p = ptr_gen(cxxrand);                       // OK

  3. OS/390 C++ does not allow functions to be declared with a function or
     an array as its return type:

       template <class InputIterator, class OutputIterator,class result)

          OutputIterator adjacent_difference(InputIterator first,

                                             InputIterator last,

                                             OutputIterator result);



       main() {

          int number[10];

          int different[5];

          adjacent_difference(number,

                              number + 5,

                              different);   // error for OS/390 C/C++

       }

     In the above example, the compiler attempts to create an instantiation
     that returns an array int[], which is not allowed in OS/390 C/C++:

       int[] adjacent_difference(int*, int*,  int*)

     To work around this problem, cast the int array to pointer to int:

       adjacent_difference(number,number + 5, (int *) different);   // OK

Linking:

Repository handling in the compiler is imperfect, so you may experience
various problems during the link step. The problems are generally of two
kinds: duplicate symbols or unresolved symbols. The duplicate symbol
problem is not fatal, since the symbols are weak (compiler generated) in
that case. When it comes to large projects, however, it may cause
unacceptable code bloat (extra code generated by the compiler when it
separates the template instantiation files into the TEMPINC directory). To
overcome this problem, this adaptation simulates separate template
implementation. Compiling templates using the tempinc compile option,
minimizes code bloat as there are less duplicate symbols. The problem with
undefined symbols is also caused by imperfect repository handling, but may
require manual intervention. The general rule is: if you get unresolved
symbol errors, explicit instantiation will most likely help. For example:

Unresolved:

  __alloc<0,0>::allocate(unsigned long)

  __alloc<0,0>::deallocate(void *, unsigned long)

To work around this problem, just instantiate __alloc<0,0> explicitly in a
module:

  template class __alloc<0,0>;
