CS 342 Lecture -*- Outline -*- * Information Hiding in C ** scopes of declarations: file and (remainder of) function, blocks no declaration has scope that extends beyond a file (but using exports and imports there is a way to share defintions among files) scope is entire file: declarations outside any function (including functions) local to a function: declarations within body of function local to a block: decl within a block (e.g., { int x; ...}) ** definition vs. declaration a definition allocates storage, or provides an implementation of a fun (called an object in the reference manual) int x; foo(x) { return(x+1); } a declaration describes attributes extern int x; extern int foo(); some constructs are both int x; ** export/import mechanism (files are modules) objects (names of cells or functions) are: exported by giving them the attribute extern default for functions and defs outside functions hidden by giving them attribute static objects are imported by declaring them to be extern ** lifetimes: (storage classes, extent -- an Algol 68 term) *** whole program's execution (called static extent in C) both extern and static -initialized when program starts running (if have initializer) -only one instance (object) -default for functions and defs outside functions (i.e., extern definitions) static variables like own variables in Algol 60 scope limited, but lifetime is infinite *** limited to activation of a function called auto (automatic) in C allocated on the run-time stack -more than one instance if have recursion *can be placed in registers! -default for function and block locals, and register vars **Info hiding: use static to hide information within a file prevents clients of external procedures from accessing data defined in the file. allows procedures in the same file to manipulate data -only perfectly safe if clients are never allowed to store the data (as in this example) ------------ /* stars database */ #include typedef struct {char *name; double ra, decl, distance, brightness; } star_rec; #define DBSIZE 100 static star_rec stars[DBSIZE]; /* the database */ static int stars_size = 0; /* numbers of stars in the data base */ void star_insert(s) star_rec s; { if (stars_size >= DBSIZE) { fprintf(stderr, "too many stars\n"); return; } stars[stars_size++] = s; } double star_brightness(nm) char *nm; { register star_rec *ps; for (ps = stars; ps < &stars[DBSIZE]; ps++) { if (strcmp(ps->name, nm) == 0) { return(ps->brightness); } } fprintf(stderr, "no such star\n"); return((double) 0.0); } /*******************************/ /* main program, separate file */ typedef struct {char *name; double ra, decl, distance, brightness; } star_rec; extern void star_insert(); extern double star_brightness(); main() { static star_rec algol = {"Algol", 3.125, 40.916, 75, 2.1}; star_insert(algol); printf("%le\n", star_brightness("Algol")); } -------------------------- *Another information hiding problem. hiding implementation of data structures that are passed around *preventing access, discovery, modification e.g., the interval type below problems: users have to know structure of intervals => cannot be sure that lower is always less than upper => users may circumvent the routines on intervals ---------------- /* intervals */ #define NULL 0 typedef struct {double lower, upper} interval_val; typedef interval_val *interval; interval interval_create(l,u) double l,u; { extern char *malloc(); interval temp; temp = (interval) malloc(sizeof(interval)); if (l < u) { temp->lower = l; temp->upper = u; } else { /* error */ temp = NULL; } return(temp); } int interval_contains(iv,d) interval iv; double d; { return((iv->lower <= d) && (d <= iv->upper)); } ----------------