5.4   C++ Interpretation

Tornado supports both C and C++ as development languages; see VxWorks Programmer's Guide: C++ Development for information about C++ development. Because C and C++ expressions are so similar, the WindSh C-expression interpreter supports many C++ expressions. The facilities explained in 5.3 The Shell C-Expression Interpreter are all available regardless of whether your source language is C or C++. In addition, there are a few special facilities for C++ extensions. This section describes those extensions.

However, WindSh is not a complete interpreter for C++ expressions. In particular, the shell has no information about user-defined types; there is no support for the :: operator; constructors, destructors, and operator functions cannot be called directly from the shell; and member functions cannot be called with the . or -> operators.

To exercise C++ facilities that are missing from the C-expression interpreter, you can compile and download routines that encapsulate the special C++ syntax. Fortunately, the Tornado dynamic linker makes this relatively painless.

5.4.1   Overloaded Function Names

If you have several C++ functions with the same name, distinguished by their argument lists, call any of them as usual with the name they share. When the shell detects the fact that several functions exist with the specified name, it lists them in an interactive dialogue, printing the matching functions' signatures so that you can recall the different versions and make a choice among them.

You make your choice by entering the number of the desired function. If you make an invalid choice, the list is repeated and you are prompted to choose again. If you enter 0 (zero), the shell stops evaluating the current command and prints a message like the following, with xxx replaced by the function name you entered:

undefined symbol: xxx

This can be useful, for example, if you misspelled the function name and you want to abandon the interactive dialogue. However, because WindSh is an interpreter, portions of the expression may already have executed (perhaps with side effects) before you abandon execution in this way.

The following example shows how the support for overloaded names works. In this example, there are four versions of a function called xmin( ). Each version of xmin( ) returns at least two arguments, but each version takes arguments of different types.

-> l xmin 
"xmin" is overloaded - Please select: 
    1: _xmin(double,double) 
    2: _xmin(long,long) 
    3: _xmin(int,int) 
    4: _xmin(float,float) 
Enter <number> to select, anything else to stop: 1 
                _xmin(double,double): 
3fe710 4e56 0000        LINK    .W      A6,#0 
3fe714 f22e 5400 0008   FMOVE   .D      (0x8,A6),F0 
3fe71a f22e 5438 0010   FCMP    .D      (0x10,A6),F0 
3fe720 f295 0008        FB      .W      #0x8f22e 
3fe724 f22e 5400 0010   FMOVE   .D      (0x10,A6),F0 
3fe72a f227 7400        FMOVE   .D      F0,-(A7) 
3fe72e 201f             MOVE    .L      (A7)+,D0 
3fe730 221f             MOVE    .L      (A7)+,D1 
3fe732 6000 0002        BRA             0x003fe736 
3fe736 4e5e             UNLK            A6 
value = 4187960 = 0x3fe738 = _xmin(double,double) + 0x28
-> l xmin "xmin" is overloaded - Please select: 1: _xmin(double,double) 2: _xmin(long,long) 3: _xmin(int,int) 4: _xmin(float,float) Enter <number> to select, anything else to stop: 3 _xmin(int,int): 3fe73a 4e56 0000 LINK .W A6,#0 3fe73e 202e 0008 MOVE .L (0x8,A6),D0 3fe742 b0ae 000c CMP .L (0xc,A6),D0 3fe746 6f04 BLE 0x003fe74c 3fe748 202e 000c MOVE .L (0xc,A6),D0 3fe74c 6000 0002 BRA 0x003fe750 3fe750 4e5e UNLK A6 3fe752 4e75 RTS _xmin(long,long): 3fe7544e560000 LINK .W A6,#0 3fe758202e0008 MOVE .L (0x8,A6),D0 value = 4187996 = 0x3fe75c = _xmin(long,long) + 0x8

In this example, the disassembler is called to list the instructions for xmin( ), then the version that computes the minimum of two double values is selected. Next, the disassembler is invoked again, this time selecting the version that computes the minimum of two int values. Note that a different routine is disassembled in each case.

5.4.2   Automatic Name Demangling

Many shell debugging and system information functions display addresses symbolically (for example, the l( ) routine). This might be confusing for C++, because compilers encode a function's class membership (if any) and the type and number of the function's arguments in the function's linkage name. The encoding is meant to be efficient for development tools, but not necessarily convenient for human comprehension. This technique is commonly known as name mangling and can be a source of frustration when the mangled names are exposed to the developer.

To avoid this confusion, the debugging and system information routines in WindSh print C++ function names in a demangled representation. Whenever the shell prints an address symbolically, it checks whether the name has been mangled. If it has, the name is demangled (complete with the function's class name, if any, and the type of each of the function's arguments) and printed.

The following example shows the demangled output when lkup( ) displays the addresses of the xmin( ) functions mentioned in 5.4.1 Overloaded Function Names.

-> lkup "xmin" 
_xmin(double,double)    0x003fe710 text         (templex.out) 
_xmin(long,long)        0x003fe754 text         (templex.out) 
_xmin(int,int)          0x003fe73a text         (templex.out) 
_xmin(float,float)      0x003fe6ee text         (templex.out) 
value = 0 = 0x0