CS 228 meeting -*- Outline -*- * Modules (HR 2) ** what modules are (HR 2.1, HR 2.4) ---------------------- MODULARITY AND MODULES To make a shirt: do we buy cotton, plastic, steel? or thread, buttons, needles? or fabric, sewing machines? To build a car: do we buy rubber, steel, plastic? or wheels, axles, etc.? or wheel assemblies, engines, etc? def: a *module* is a collection of related parts. ---------------------- --------------------------- MODULES IN SOFTWARE def: a *module* is a collection of related objects (variables and constants) functions types macros usually in a separately compilable unit, which offers the possibility of hiding information. For us a module will be a .h file, and (usually) one .C file. Examples: prompt.h and prompt.C IOVec.h and IOVec.C pretend_bool.h --------------------------- may have no .C files (as in pretend_bool.h) or several (as perhaps is the case for math.h In the sense of grouping with information hiding, each C++ source file is a module, but clearer to imagine it like this. ----------------------------- INFORMATION HIDING client =================== module interface (.h) implementation (.C) ------------------------------- Q: does this resemble any picture we've seen before? yes: abstraction! The module boundary is documented by the specification (in the .h file) implementation in the .C file unless already in the .h file. ------------------------------- // Sort.C -- client #include "swap.h" ... swap(vec[i], vec[j]); ... // swap.h -- interface extern void sway(int & x, int & y); // MODIFIES: x, y // POST: x is y and y is x // swap.C -- implementation #include "assign2.h" #include "swap.h" void swap(int& x, int& y) { assign2(x, y, y, x); } ----------------------------- draw Booch diagram ** why to use them *** reuse (2.2) ---------------------- WHY USE MODULES? Possibility of off-the-shelf components - don't have to reinvent algorithms - can write at a higher level - saves money - programs more reliable - programs more efficient ---------------------- can write at higher level, because don't start with base language. saves money because cost of developing component can be shared with other customers reliability and efficiency increased by reuse and market pressures This is certainly a (welcome) trend of late, with DLLs etc bringing reuse to the world. *** locality ---------------------------- Module specification is a contract - allows division of labor - separation of concerns - implementation independence - assignment of blame ---------------------------- when debugging, if use meets spec's precondition, then error is fault of implementation, otherwise vice versa (see also p.97) This prevents redundant checking for errors (both caller and impl.) ** how to use them (2.4) *** information hiding, file scope, and linkage in C++ (2.7) --------------------------------- WHAT CAN BE VISIBLE TO CLIENTS What can be visible when linking (.C): variables functions (constants) Not involved at link time: typedefs enum #define ---------------------------------- the linker only hooks up functions and objects, all the rest is compiled away compile time ----------------------------------- INFORMATION HIDING WITH C++ To Hide (from linkers): static int myPrivateVar; static void MyOwnFunction(int & x) // POST: x == myPrivateVar { // ... } const int PRIVATE_NUM = 3; To make visible to clients (linkers): int myPublicVar; void FunForYou(int & x) // POST: x == myPublicVar { // ... } extern const int VISIBLE_NUM = 4; ------------------------------------ so default linkage is extern(al) for objects and functions and internal for constants *** guidlines for header files (p.67, p.87) note these are guidelines, not enforced by C++ ---------------------------------- WHAT GOES IN A HEADER (.h) FILE // Example.h #ifndef Example_h #define Example_h 1 #include const char AT_SIGN = '@'; typedef char string[]; enum Error {IO, RANGE, ACCESS}; extern void swap(int & x, int & y); // MODIFIES: x, y // POST: x is y and y is x extern float delta; #endif ---------------------------------- in general: preprocessor directives and declarations, not definitions (of functions or variables) constant definitions ok because they have internal linkage so don't produce errors if included twice in a program more specifically, can include constant definitions, type definitions, and object (function and variable decls). When including function declarations, we'll require the spec, but we'll leave the spec out of the implementation file (don't duplicate it) Explain what #ifndef does, and #define, that these are needed if you make any definitions (e.g., of constants and types) to prevent multiple inclusion and thus errors from multiple definitions. ------------------------------- MULTIPLE INCLUSIONS // foo.h #include "Example.h" // bar.h #include "Example.h" // typical.C #include "foo.h" #include "bar.h" Example.h / \ foo.h bar.h \ / typical.C #ifndef Example_h #define Example_h 1 ... #endif #ifndef Example_h #define Example_h 1 ... #endif ------------------------------- It would be nice if C++ did this right automatically!!! (sigh) Explain that the second ifndef is false, so body ignored. You'll often see the 1 left out, it's the default in #define ------------------------ WHAT GOES IN .C FILES // Example.C #include "Example.h" #include "assign.h" void swap(int & x, int & y) { assign2(x, y, y, x); } float delta = 3.4; ------------------------ in general, need to include the .h file for type defs, etc. and then need to define the functions and variables. *** examples look, on-line at the rand and password modules in the HR directory note the abstract specs in the header files, and concrete specs in the implementation files. *** using libraries ---------------------------- NEED FOR LIBRARIES # Makefile PUB = /home/cs228/public CPP = $(PUB)/bin/ansicpp OBJECTS = selsort.o Sort.o IOVec.o \ sort.o prompt.o selsort.exe: $(OBJECTS) $(CPP) -o selsort.exe $(OBJECTS) Sort ------> swap ------> assign2 uses uses -------------------------------- No reason writer of Sort should care that swap uses assign2 so need way to protect user from that error -------------------------------- MAKEFILE WITH LIBRARIES #Makefile LIB = $(PUB)/lib LIBS = -L$(PUB)/lib -lcs228 HDIR = $(PUB)/include INCLUDES = -I$(HDIR) OBJECTS = selsort.o Sort.o IOVec.o selsort.exe: $(OBJECTS) $(CPP) -o selsort.exe $(OBJECTS) \ $(LIBS) Sort.C: Sort.h swap.h $(CPP) -c $(INCLUDES) Sort.C ---------------------------- using our own library in the selsort example -L/home/cs228/public/lib makes linker look in that directory -lcs228 looks for file libcs228.a show makefile in $PUB/lib use of ar to make a library