|
Note for IBM OS/390 C/C++ Users
Known Problems
Compiling:
- 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.
- 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
- 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:
__default_alloc_template<0,0>::allocate(unsigned
long)
__default_alloc_template<0,0>::deallocate(void *, unsigned
long)
To work around this problem, just instantiate __default_alloc_template<0,0>
explicitly in a module:
template class __default_alloc_template<0,0>;
Useful Links
Check out :
http://www.software.ibm.com/ad/c390/cmvsstlp.htm
|