------------------------------------------------------------------------------ System Dependancies in C complilers Size (and byte order) of the basic C types short, int, long, float, double, long double, void * wheather char is signed or unsigned Memory Alignment for pointers and chars sizeof( char ); vs sizeof( struct { char c; } ); vs sizeof( struct { void *ptr; char c; } ); IE: does stored pointers need to be memory alignmented do structures have to be aligned. what about strings? (this last is very unlikely) Integer division/modulus operation with negitive operands division - how is it to truncate the number 5/2 --> 2 5/-2 --> -2 or -3? modulus -- what range is the output n%p --> 0 to p-1 -n%p \ / 0 to p-1 n%-p > --> < -(p-1) to 0 -n%-p / \ -p to -1 ANSI standard guarantees that the identity is true (x/y)*y + x%y --> x Order of Evaluation (operand evaluation order not operator order) EG: which + is performed first left-to-right ? or right-to-left (a+b)*(c+d) This is only a problem when you have side-effects Examples: x = 2*x/3 with x=5 left-right --> x=3 (x=2 is wrong) y = (x++) + (x*2) with x=1 left-right --> y=5 (correct) right-left --> y=3 z = x++ + ++x + x++ with x=2 increment failure x != 5 x++ in middle of staement z == 10 x++ at end of statement z == 8 f() + g() a[i] = i++ x = (temp = i*2) + temp; /* to be equivelent to x = i*2 + i*2 */ Order of Evaluation for functional arguments f( x++, x++, x++) NOTE: this is NOT specified by any C specification anywhere Structure assignation and as arguments is it passed by value? Pointer only? struct s a = (struct s) b funct( (struct s) c ); /* any warnings ? */ Implicit Structure initialization in functions NOTE: sun fails for this String Constant consolidation #define STRING "testing" char *s1 = STRING; char *s2 = STRING; if ( s1 == s2 ) ????? Keywords void, const, volatile Anonymous unions within a structure (forbiden by ANSI) struct s { int a; union { int i; char c; }; } x; x.i works IE; no union part. String concatination by compiler "abc" "xyz" compliled as "abcxyz" Level of prototyping accepted extern int funct( int a; int b; ); extern int funct( int a, b ); extern int funct( int; int; ); extern int funct( int... ); extern int funct(); Pre-processing depandancys ANSI macro operators #define str(STR) printf("%s\n", #STR) /* stringize */ #define decl(type) extern void funct_##type() /* concatination */ NOTE: sun allows stringize but not the concatination methods non-ANSI macro concatination -- SUN allows both of these #define ident(a) a #define cat(a,b) ident(a)b or #define cat(a,b) a/**/b Pre-processor lines can indent as per ANSI -- SUN cpp does not allow this | #define ~~~~~~~~~~~ Macro expansion in strings (WRONG -- the stringize `#' operator ) #define str(STR) printf("STR\n") Library depandancies printf insertion types %p -- pointer %n -- return number conversion scanf character type %[] ranges in that type %[a-z] NOTE: this is undefined in ANSI can memcpy() copy overlaping areas properly (yes sun -- no solaris) index() or strchr() ( strings.h or string.h ) ------------------------------------------------------------------------------ Operations that should be correct on all C compilers Logical Short-Circuiting. False && (expression not evaluated) True || (expression not evaluated) Note: Watch out that side effects may or may not be executed This is typically used for pointer evaluation and within macro expressions. EG: if( p!=NULL && p->next!=NULL ) statement; instead of if( p!=NULL ) if( p->next!=NULL ) statement; OR if( p==NULL || p->next==NULL ) statement; is equivelent to if( p==NULL ) statement; else if( p->next==NULL ) statement; Also ensure that short-cuiting is perfromed for the tertary operator True ? (evaluated) : (not evaluated) false ? (not evaluated) : (evaluated) which is a major player in macro operations. ------------------------------------------------------------------------------ Testing Example (Auto-increment) /* the test code */ main() { int x, y, z; x = 1; y = (x++) + (x*2); printf(" x=1; y = (x++) + (x*2); ==> x=%d, y=%d\n", x, y); x = 2; z = x++ + ++x + x++; printf(" x=2; z = x++ + ++x + x++; ==> x=%d, z=%d\n", x, z); } NOTE: from "Comprehensive C p37, this seems to be the correct result) ``x++ Post-Increment Increment x, return OLD value of x'' EG: increment is actually in MIDDLE on statement. solaris gcc 2.95.3 (lyrch, system programmer machine) x=1; y = (x++) + (x*2); ==> x=2, y=3 x=2; z = x++ + ++x + x++; ==> x=3, z=8 Result: associativity is right to left (WRONG), post auto-increment is performed AFTER statement is finished solaris gcc 2.8.1 (gucis, student unix server) x=1; y = (x++) + (x*2); ==> x=2, y=3 x=2; z = x++ + ++x + x++; ==> x=3, z=8 Result: as per previous solaris machine linux gcc 2.95.2 (kobold, anthony's PC workstation) x=1; y = (x++) + (x*2); ==> x=2, y=3 x=2; z = x++ + ++x + x++; ==> x=5, z=9 Result: associativity is right to left (WRONG), post-increment acts really strangely z = 2 + 3 + 4! linux gcc 2.96 (buzz, david's PC workstation) x=1; y = (x++) + (x*2); ==> x=2, y=3 x=2; z = x++ + ++x + x++; ==> x=5, z=9 Result: As per above linux machine ------------------------------------------------------------------------------