Departures from C/C++: * See Scoping and Linkages for details on extern, import, LTextern, LTimport, etc. * See ::/LT/Doc/Directives.TXZ. * See the demo::/LT/Demo/OldSchool/Demo1/Compatibility1.SPP, ::/LT/Demo/OldSchool/Demo2/Compatibility2.SPP and ::/LT/Demo/GameStarters/FlightSim.CPZ if you want to operate conventionally (old school). * Built-in types include I0,I8,I16,I32,I64 for signed 0-8 byte ints and U0,U8,U1 6,U32,U64 for unsigned 0-8 byte ints and F64 for 8 byte floats. U0 void I8 char U8 unsigned char I16 short U16 unsigned short I32 int U32 unsigned int I64 long (64-bit) U64 unsigned long (64-bit) F64 double * Function with no, or just default args can be called without parenthesis. * Default args don't have to be on the end. This code is valid: U0 Test(I64 i=4,I64 j,I64 k=5) { coutln i,j,k; } Test(,3); * When dealing with function addresses, precede the name with "&". * There is no main() function. Any code outside of functions gets executed on start-up, in order. * Var arg cnts (...) are accessed with argc and argv[] which are predefined invisible local var in any function with "..." as args. * Allows "5<i<j+1<20" instead of "5<i && i<j+1 && j+1<20". * switch statements always use a jump table. Don't use them with cases with really big, sparse ranges. * Allows ranges like "case 4...7:" in switch statements. * nobound_switch can be used if you know a switch statement will not exceed the lowest or highest case values. It's a little faster because it doesn't check. * noreg or reg can be placed before a function local var name. You can, optionally, specify a register after the reg keyword. * interrupt, public, argpop or noargpop are function flags. * A nounusedwarn statement will suppress an unused var warning. * You can have multiple member vars of a class named "pad" or "reserved", and it won't issue warnings. * Type casting is done with ><(classname) and is postfix. To typecast int or F64, use ToI64(), ToBool() or ToF64(). (LoseThos follows normal C float<-->int conversion, but sometimes you want to override. These functions are better than multiplying by "1.0" to convert to float.) * The "`" operator raises a base to a power. * A single quote can encompass multiple characters. 'ABC' is equal to 0x434241. * LoseThos operator precedence `,>>,<< *,/,% & ^ | +,- <,>,<=,>= ==,!= && ^^ || :,? =,<<=,>>=,*=,/=,&=,|=,^=,+=,-= * Use OptOn(OPTf_STD_C) to use C precedence. * You can use OptOn(OPTf_PAREN_WARN) to find unnecessary parentheses in code. * With the #exe{} feature in your src code, you can place programs that insert text into the stream of code being compiled. See #exe {} for an example where the date/time and compile-time prompting for configuration data is placed into a program. The StreamPrintF() and StreamPutS() place text into a src program stream following the conclusion of the #exe{} blk. * No #define functions exist (I'm not a fan) * No type-checking * Can't use <> with #include, use "". * cout works with commas, not << and has no endl or other codes. It is very limited in flexibility, but is handy. Use coutln to print a carriage return after other stuff. An alias for cout is dbgo or dbgoln and is useful for debugging--I often place debug output all over the place and do a Grep() to locate them all. * "$" is an escape character. Two dollar signs signify an ordinary $. See ::/LT/Doc/Dollar.TXZ. In asm or C+ code, it also refers to the instruction's address. * union is more like a class, so you don't referrence it with a union label after you define it. Some common unions are declared in Adam1a.HPZ for 1,2,4 and 8 byte objects. If you place a type in front of a union declaration, that is the type when used by itself. See ::/LT/Demo/SubIntAccess.CPZ. * class member vars can have meta data. fmtstr and fmtdata are two meta data types now used. All compiler structures are saved and you can access the compiler's info about classes and vars. See ::/LT/Demo/ClassMeta.CPZ and LtfFormDo(). * See ::/LT/Demo/Exceptions.CPZ. try{} catch{} and throw are different from C++. throw is a function with var ("...") args. The values passed in throw() can be accessed from within a catch{} using the Fs->except_argc and Fs->except_a rgv[] vars. Within a catch {} blk, set the var Fs->catch_except to TRUE if you want to terminate the search for a handler. By convention, the first arg of exc ept_argv[] specifies the exception type num. A list of assigned exception types can be found at EXCEPT_LOCAL. For a handler that will catch all excepts, you can use CatchAll(). * A function is available similar to sizeof which provides the offset of a member of a class. It's called offset. You place the class name and member inside as in offset(classname.membername). It has nothing to do with 16-bit code. Both sizeof and offset only accept one level of member vars. That is, you can't do sizeof(classname.membername.submembername). * There is no continue statement. Use goto. * No bit field support, but there are bit access library routines. * lock{} can be used to apply asm LOCK prefixes to code for safe multicore read-modify-write accesses. The code bracked with have LOCK asm prefix's applied to relevant instructions within. It's a little shoddy. See ::/LT/Demo/MultiCore/Lock.CPZ. * There is a function called MSize() which gives the size of an object allocated off the heap. For larger size allocations, the system rounds-up to a power of two, so MSize() lets you know the real size and you can take full advantage of it. * You can Free() a NULL ptr. Useful variants of MAlloc() can be found Here. Each task has a heap and you can MAlloc and Free off of other task's heaps, or make an independent heap with IndependentHeapCtrlInit(). * The stk does not grow because virtual mem is not used. I recommend allocating large local vars from the heap. You can change DFT_STK and recompile OSMain or request more when doing a Spawn(). * All values are extended to 64-bit when accessed. Intermediate calculations are done with 64-bit values. I16 i; I32 j; j=i=0x12345678; //Resulting i is 0x5678 but j is 0x12345678 I64 i=0x8000000000000000; coutln i>>1; //Result is 0xC000000000000000 as expected U64 u=0x8000000000000000; coutln u>>1; //Result is 0x4000000000000000 as expected I32 i=0x80000000; //constant is loaded into a 64-bit register var. coutln i>>1; //Result is 0x40000000 I32 i=-0x80000000; coutln i>>1; //Result is 0xC0000000 as expected PrintF Family MSPrintF() is like SPrintF() but it returns a MAllocated str. It is vary handy because you don't have to worry about overflow. Auto(U8 *fmtstr,...) sends text to the current task's input buffer. AutoStr(U8 *fmtstr,...) sends text of an AutoFile to the keyboard stream of the current TASK but can also do mouse cmds. XTalk(TaskStruct *task,U8 *fmtstr,...) and text to another task's input buffer. XTalkStr(TaskStruct *task,U8 *fmtstr,...) sends text of an AutoFile to the keyboard stream of another TASK but can also do mouse cmds. LtfPutS(Ltf *l,U8 *src) and LtfPrintF(Ltf *l,U8 *fmtstr,...) send text to a linked text file. You can buffer to a Ltf and save it, providing the functionality of fprintf. See ::/LT/Demo/Dsk/FPrintF.CPZ. Adam(U8 *fmtstr,...) send text to the adam task to be compiled and run. AdamLog(U8 *fmtstr,...) and AdamErr(U8 *fmtstr,...) send text to the adam task to be displayed. StreamPrintF(U8 *fmtstr,...) and StreamPutS(U8 *src) send text to the stream of code being compiled and must reside in a #exe{} blk. GrPrintF(GrBitMap *base,I64 x,I64 y,U8 *fmtstr,...) and GrPutS(GrBitMap *base,I64 x,I64 y,U8 *src) plots text in graphics mode. GrVPrintF() and GrVPutS() will print vertically. ExePrintF(U8 *fmtstr,...) and ExePutS(U8 *src) compile and execute a string. Note: It returns the result of the last executed expression. Note: If no PutS variant is available, you can use PrintF("%s",src). The PrintF() family supports extended format codes. See SPrintFJoin2(). %[-][0][width][.decimals][flags][hsub_fmt][main_fmt] flags: * 't' is a flag which will truncate to field width. * ',' is a flag which will add commas every three digits in a %d, %f, %g, %e and %n entries. * '$' is a flag which affects the %Q entry, converting '$' to "\34". * 'k' is a flag which forces 1000 instead of 1024 on integer with sub_fmts. sub_fmt: On date or time entries, the sub_format specifies the format. See ::/LT/Demo/DateTime.CPZ. On "%n", "%d" or "%u", the sub_fmt causes thousands mode. "%h?n" will pick a var exponent multiples of three unit, while "%h-3n", for example, will display milli units or "%h6n" will display mega units. The 'k' flag is always on for "%n". See ::/LT/Demo/PrintF.CPZ. * In float formatting, do not exceed 18-digits before or after the decimal point because the numbers before and after the decimal point are stored in 64-bits. Use exponentiated forms to avoid this. * "%n" will print a floating point in engineering notation, exponents being multiples of three. If it has a sub_fmt code, it will display scientific units letters. * "%S" will print a Define entry. * "%C" will print a ToUpper character. * "%F" will print a text file. * "%P" will display a PSECT expression which is good for ptrs or addresses. * "%T" and "%D" will display a date or time and the format is selected with a subcode, entered after a "h". Example: "%20h1D" uses date format code "1". See ::/LT/Demo/DateTime.CPZ, MSPrintFDate() and MSPrintFTime() for subcodes. * "%z" will display a subentry of an enumerated list of text entries. It calls ListEntryPoint(). Pass entry_num first, list second. * "%Z" will display a Define subentry. Pass entry_num first, list_systext second. * "%Q" will convert "\" to "\\" and quote to backslash quote. (For use in creating strs in strs.) * "%q" will reverse a "%Q".