Writing TAPS using C++

This guide assumes that you have a working Unix/Cygwin installation and that you have been able to compile 'C' TAPs.

Getting a C++ toolchain built

Download tap_toolchain-1.1.tar.gz from http://developer.berlios.de/project/showfiles.php?group_id=4128 . This needs to be unpacked into a folder. Normally the only steps needed are to create a folder /usr/local/topfield-gcc (writeable by you) and running make. You can look at the Readme extracted from the toolchain source for more instructions. In order to get a c++ compiler you need to change 2 instances of --enable-languages=c to --enable-languages=c,c++ in the top level makefile, then run make.

If you're feeling adventurous, you can disable the annoying warning about '#pragma once' being deprecated by editing gcc-2.95.2/gcc/cccp.c and commenting out the following lines

if (!instack[indepth].system_header_p)
      warning ("`#pragma once' is obsolete");

I happen to like #pragma once as it appeals to the laziness in me :-)

Fixing libtap.a

The libtap.a shipped by topfield in the TAP development pack, and downloaded from many other sites contains an implementation of void* operator new(size_t size) which is apparently broken, along with no matching implementation for void operator delete(void* ptr). Nice. In order to avoid the hassle of defining operator new/delete on a per-class basis it's important to get rid of this definition of operator new so that the (working) one defined in libc++utils.a can be used. Here's how

  • copy libtap.a to another location. Keep a backup copy too.
  • extract the contents using 'ar x libtap.a' - this should extract init.o
  • run 'mips-objcopy -N __builtin_new init.o' - this removes the symbol __builtin_new from init.o
  • re-create the archive - rm libtap.a; ar q libtap.a init.o
  • replace the original libtap.a with your newly fixed one

Compiler Options

Make sure that you have -fno-weak in your c++ compiler options, in addition to those specified for C compilation. Without this the address resolution of functions with weak linkage can be double counted, leading to a crash.

What Works

  • Classes, Inheritance
  • Virtual Functions, but you must make sure that the vtables get fixed up - this requires a makefile step and initialization in code before any virtual functions are called. See the code for libframework? and it's example project.
  • Stack and Heap allocation for classes
  • C++ Syntax (declare variables away from beginning of scope, default parameters)
  • Templates (but not with virtual member functions)

What Should Work

  • Multiple Inheritance

What Doesn't Work

  • Pointers to non-static member functions
  • Template classes with virtual functions
  • initialization of static intances of objects - the memory is set to zero, but no ctor/dtor called on tap load/exit