C++ Producer Guide

March 1998

next section previous section current document TenDRA home page document index

2.7.1 - Common porting problems
2.7.2 - Porting libio

2.7. Standard library

At present the default implementation contains only a very small fraction of the ISO C++ library, namely those headers - <exception>, <new> and <typeinfo> - which are an integral part of the language specification. These headers are also those which require the most cooperation between the producer and the library implementation, as described in the previous section.

It is suggested that if further library components are required then they be acquired from third parties. It should be noted however that such libraries may require some effort to be ported to an ISO compliant compiler; for example, some information on porting the libio component of libg++, which contains some very compiler-dependent code, are given below. Libraries compiled with other C++ compilers may not link correctly with modules compiled using tcc.

2.7.1. Common porting problems

Experience in porting pre-ISO C++ programs has shown that the following new ISO C++ features tend to cause the most problems:

  1. Implicit int has been banned.
  2. String literals are now const , although in simple assignments the const is implicitly removed.
  3. The scope of a variable declared in a for-init-statement is the for statement itself.
  4. Variables have linkage and so should be declared extern "C" if appropriate.
  5. The standard C library is now declared in the std namespace.
  6. The template compilation model has been clarified. The notation for explicit instantiation and specialisation has changed.
  7. Templates are analysed at their point of definition as well as their point of instantiation.
  8. New keywords have been introduced.
Note that many of these features have controlling #pragma directives, so that it is possible to switch to using the pre-ISO features.

2.7.2. Porting libio

Perhaps the library component which is most likely to be required is <iostream>. A readily available freeware implementation of a pre-ISO (i.e. non-template) <iostream> package is given by the libio component of libg++. This section describes some of the problems encountered in porting this package (version 2.7.1).

The tcc compiler flags used in porting libio were:

	tcc -Yposix -Yc++ -sC:cc
indicating that the POSIX API is to be used and that the .cc suffix is used to identify C++ source files.

In iostream.h, cin, cout, cerr and clog should be declared with C linkage, otherwise the C++ producer includes the type in the mangled name and the fake iostream hacks in stdstream.cc don't work. The definition of EOF in this header can cause problems if both iostream.h and stdio.h are included. In this case stdio.h should be included first.

In stdstream.cc, the correct definitions for the fake iostream structures are as follows:

	struct _fake_istream::myfields {
	    _ios_fields *vb ;		// pointer to virtual base class ios
	    _IO_ssize_t _gcount ;	// istream fields
	    void *vptr ;		// pointer to virtual function table
	} ;

	struct _fake_ostream::myfields {
	    _ios_fields *vb ;		// pointer to virtual base class ios
	    void *vptr ;		// pointer to virtual function table
	} ;
The fake definition macros are then defined as follows:
	    extern "C" _fake_ostream NAME = { { &NAME.base, 0 }, .... } ;

	    extern "C" _fake_istream NAME = { { &NAME.base, 0, 0 }, .... } ;
Note that these are declared with C linkage as above.

In stdstrbufs.cc, the correct definitions for the virtual function table names are as follows:

	#define filebuf_vtable		__vt__7filebuf
	#define stdiobuf_vtable		__vt__8stdiobuf
Note that the _G_VTABLE_LABEL_PREFIX macro is incorrectly defined by the configuration process (it should be __vt__), but the ## directives in which it is used don't work on an ISO compliant preprocessor anyway (token concatenation takes place after replacement of macro parameters, but before further macro expansion). The dummy virtual function tables should also be declared with C linkage to suppress name mangling.

In addition, the initialisation of the standard streams relies on the file pointers stdout etc. being constant expressions, which in general they are not. The directive:
	#pragma TenDRA++ rvalue token as const allow
will cause the C++ producer to assume that all tokenised rvalue expressions are constant.

In streambuf.cc, if errno is to be explicitly declared it should have C linkage or be declared in the std namespace.

In iomanip.cc, the explicit template instantiations should be prefixed by template. The corresponding template declarations in iomanip.h should be declared using export (note that the __GNUG__ version uses extern, which may yet win out over export).

Part of the TenDRA Web.
Crown Copyright © 1998.