The following appear to be commonly encountered problems. Please send mail to boehm@xerox.com if you have useful additions to this list. 1. A missing ; can cause two adjacent expressions (usually assignments) to be parsed as one. This is likely to generate strange error messages, such as "Non-function used as operator". 2. A reference to an uninitialized product or union variable will get caught as a reference to an address past the end of the heap or to location 0. The resulting message will indicate a segmentation violation. (This, like all runtime errors, may eventually be followed by an illegal instruction message, which may be ignored. On the vax, with tracing is enabled, a stack trace will be provided.) 3. Floating point constants are limited to 9 digits before and 9 digits after the decimal point. (4 in the Vax implementation.) The relative precedences of '.' and exponentiation are counterintuitive. 4. Dbx and adb stack traces are sometimes useful for figuring out where things went wrong. They may omit calls that were expanded in-line and certain tail-recursive calls. Arguments may not be accurate. (Most Russell functions appear to be called with a single argument, namely a pointer to the activation record for the called function. Arguments start at an offset of 4 bytes from the beginning of this activation record. If the assembly language function name is prefixed by an "F", its calling sequence is very similar to that for C functions, and adb will probably print arguments correctly. Very simple functions are normally treated in this manner.) The actual function name will be embedded in the name printed by adb. (Note that this function name normally includes a period, which must be escaped using a backslash when typing it in an adb command.) 5. Parameters or type signature components involving an operator identifier should be written with the ":" preceded by a blank. E.g. + : func[x,y: val Z] val Z is correct. The parameter specifier +: func[x,y: val Z] val Z will be interpreted as declaring parameter with name "+:". This will result in an error message pointing to the missing ":". 6. Explicit selections usually need to be specified for In and Mk operations, since none of the arguments is likely to have the correct type to select from. 7. Use double quotes for single character ChStr constants. Single quotes will normally cause digits to be interpreted as integers instead. (Of course ChStr$'2', will work fine.) 8. Unary minus has the same precedence as binary minus. This means expressions like a*-b will not get parsed in the usual way. Use parentheses. 9. It is fairly easy for a Russell compiler to implement a very general notion of constant folding. Unfortunately this has served as an excuse to put off implementing even simple constant folding. If you care about efficiency, bind constant expressions to identifiers. 10. The error message "Variable ? imported ..." (the "?" is literally there) usually indicates that a function requiring an inferred var Void parameter was called from a function without a var Void parameter. The compiler thus inserted a var Void identifier which violates the import rule. 11. Segmentation violations are generally due to uninitialized variables. 12. If the linker complains of undefined symbols, it is probably due to "bad" characters in the filenames for subcompilations. 13. In the event of complaints about not being able to infer signature, it is usually easiest to add function result signatures or signatures to declarations. Other strategies like reducing overloading by renaming identifiers may also help, but should not be necessary. 14. In response to a signature related error, the compiler may print some information starting with "Attempted to match:". This describes the last attempted (and failed) signature match before the error. It is sometimes, but not always, useful. If it doesn't make any sense to you, ignore it. 15. If y has signature "var T", then the declaration "x == y" will result in x being bound to a variable (location). When y's value changes, so does x's value. If you want to bind x to y's value at the time the declaration is evaluated, use "x == V[y]". 16. Russell generated ".o" files contain absolute addresses in the address space of the compiler that generated the file. These will no longer make sense if you change compiler versions. Thus a change to the compiler frequently requires recompilation of all Russell programs compiled with -c. If you forget to do this, the compiler is likely to die with lots of error messages.