Presentation is loading. Please wait.

Presentation is loading. Please wait.

Subprograms Support process abstraction and modularity –characteristics of subprograms are that they have a single entry point the calling entity is suspended.

Similar presentations


Presentation on theme: "Subprograms Support process abstraction and modularity –characteristics of subprograms are that they have a single entry point the calling entity is suspended."— Presentation transcript:

1 Subprograms Support process abstraction and modularity –characteristics of subprograms are that they have a single entry point the calling entity is suspended when control is transferred to subprogram control returns to calling entity upon termination of subprogram –FORTRAN allows multiple entry points Two general types of subprograms: procedures and functions Subprogram design issues: –what mode(s) of parameter passing is used? –should parameters be type checked? –can a parameter be a subprogram name? –are local variables static or stack dynamic (or other)? static variables do not permit recursion –is separate compilation of subprograms allowable? –can subprograms be generic or overloaded?

2 Subprogram Header and Parameters The subprogram header defines –the type of syntactic structure (function or procedure) –provides a name –specifies the parameter profile the number of and types of parameters –C-languages only have functions but can simulate procedures using void There are two ways that a subprogram can access data from the calling entity –nonlocal (global) variables –parameters Parameters in the header are formal parameters, parameters in the call are actual parameters There are many different forms of parameter passing –actual parameter lists may include optional parameters available in C/C++, C#, Java, Common Lisp, Python, Ruby –formal parameter lists may have initializations available in C++, FORTRAN 95, Ada, PHP, Python, Ruby –most languages pass parameters by position (positional params) but some languages also allow for keyword params so that order is not important

3 Separate/Independent Compilation Separate compilation allows for large software systems –for this to be available, the compiler needs access to info about data types used in the unit being compiled –separate compilation requires that subprograms be compiled in a proper order Java, Ada, Modula-2 and FORTRAN 90 are all like this Independent compilation allows a subprogram to be compiled without any knowledge of other subprograms –found in C, FORTRAN 77, LISP in C, the compiler still needs to type check parameters/return types so prototypes are required in FORTRAN 77, type checking was not performed in LISP, there is no compile-time type checking Pre 77 FORTRANs and Pascal are languages that allow for neither separate nor independent compilation

4 Local Variables Static storage allows for compile-time memory allocation and deallocation –ensures type checking but does not allow for recursion Stack Dynamic allows for recursion at the cost of run-time allocation/deallocation and initialization –because these are stored on a stack, referencing is indirect based on stack position and possibly time-consuming, we examine this in chapter 10 Languages and their implementations: –FORTRAN I-IV: static only –FORTRAN 77: programmer chooses (although still no recursion) –FORTRAN 90/95: static unless the subprogram is explicitly declared as recursive –ALGOL 60: first to offer stack-dynamic –Pascal, Modula-2, Ada, Java: only have stack-dynamic –C, C++: defaults to stack dynamic, but static is allowed if declared as static –in C++, variables declared in methods can only be stack-dynamic as in Java –Lisp: implicit heap dynamic

5 Parameter Passing Methods Three modes of parameter passing: –in mode (params going from prog to subprog) –out mode (params going from subprog to prog) –inout mode (both) Implementations: –Pass by Value (in) –Pass by Result (out) –Pass by Value-Result (inout) –Pass by Reference (inout) –Pass by Name (varies)

6 Implementations Pass by value: actual param used to initialize formal param but from that point forward, the formal param acts like a local variable and is entirely independent of the actual param –implemented by physical data transfer (copying the value), which could be inefficient if the variable is an array or record (structure) Pass by result: the formal param acts as a local variable (uninitialized at the beginning of the subprogram) and whose value is passed by to the actual param once the subprogram terminates –again, passing is done by physical data transfer Pass by value-result: combines pass by value and pass by result –also referred to as pass by copy –requires two copying actions, yielding the same disadvantages as with pass- by-value and pass-by-result Pass by reference: pass an access path to the variable’s stored value (a pointer) –this creates an alias between the formal and actual params –physical copying is limited to the address, not the datum, so this is more efficient if the param is an array or structure and nothing is passed back

7 Pass by Name This is an in-out mode implemented in ALGOL 60 but not used in many languages since –in fact, because it is so confusing, it has been largely been discarded as obsolete (even dangerous) Because it is so different from the previous methods, we will take a brief look –rather than passing a parameter (a value or pointer), the name of the variable is passed –in the subprogram, textual substitution takes place we replace all instances of the formal param with the characters that make up the actual param We still find this approach in many languages today, but it is used in macro substitution if the language has macro expansion –C has compile-time macro expansion by using #define –C++ and Ada use this for generic subprograms –Lisp has run-time macro substitution See the example in the notes for this slide

8 Parameter Passing in Various Languages pre FORTRAN 77: pass by reference more recent FORTRAN: pass by reference for structures and pass by value- result for simple values ALGOL 60: pass by name + pass by value as an option APL and Simula 67: pass by name ALGOL 68, C, Java, C#, PHP and others: pass by value, but where pass by reference can be simulated by passing a pointer C++: same as C but with a special reference type that does not require dereferencing –this allows for a true pass by reference form so that the programmer does not have to pass an explicit pointer ALGOL-W: pass by value-result Pascal, Modula 2: pass-by-value with pass-by-value-result as an option –the word var in the parameter list denotes pass-by-value-result Perl: all parameters are combined into an array and the array is passed by reference Ada: 3 explicit types - in, out, in out –method used is based on compiler writer’s implementation!

9 Parameter Type Checking Software reliability demands type checking Type checking compares formal and actual parameters for types, numbers, order, etc… usually at compile time –different languages have different rules for type checking makes some languages safer than others makes some more flexible than others Language rules: –F77 and earlier: no type checking at all –Pascal, Modula-2, F90, Ada, Java: type checking required –Original C, Perl, JavaScript, PHP: no type checking at all and checking number of parameters is also omitted in original C –C++: type checking required unless you use ellipses (…) for optional parameters

10 Implementing Parameter Passing Communication between calling entity and subprogram is through the runtime stack including parameter passing –by Value - copy value onto stack –by Result – copy value from stack –by Reference - place address of parameter on the stack and dereferencing in the subprogram –by Name - implemented using “Thunks”

11 Arrays as Parameters As we saw in chapter 6, a mapping function must be set up by the compiler so that an array access can be mapped into a specific memory location –in languages where separate compilation of subprograms is available, the original definition of the array will have already been compiled so that the mapping function is available when compiling the subprogram However, in languages where independent compilation is available, we need another approach –in C, C++, this is taken care of by requiring that all of the array dimensions (except for the first) is specified in the function header and function prototype void fun(int array[ ][5][10]) –in FORTRAN, any array that is passed to a subprogram must then be declared (that is, its sizes must be described in the subprogram) –in Lisp, the mapping function can be generated at run-time, or if the arrays can change dynamically, then they are implemented as linked lists and do not use a mapping function at all

12 Parameters that are Subprogram names Subprogram names might be passed as parameters –example, we want a subprogram that performs an integration estimate for area under a curve we want the subprogram to execute independently of the function, so we write it so that the we pass function’s name that we want to integrate to an integrate subprogram rather than writing a version of the subprogram for each function we might want to use double integrate(double *(f)(double x), double lowerbd, double upperbd) { double result, i; … result = f(i); … } This is available in C/C++, Fortran 90/95 and JavaScript

13 Passing Subprogram Names Passing the subprogram’s name requires –that the subprogram’s parameters and their types be passed to the subprogram along with the subprogram’s return type in the previous example, function f’s return type and its parameter’s type must all be specified this provides necessary information for type checking –in C, C++, pointers to a function are passed rather than the function name itself When passed, the correct referencing environment must be identified: –environment of the subprogram call (shallow binding) –environment of the definition of the subprogram (deep binding) –environment of the subprogram which called the subprogram passed (ad hoc binding)

14 Overloaded Subprograms Overloaded subprograms share the same name Each subprogram must have different types of parameters and/or different number of parameters –at run-time, the proper subprogram is invoked based on which params are passed –using overloaded subprograms is less efficient because the run-time environment must determine which set of code gets executed –but it provides a programmer with the flexibility to define a given subprogram to operate on different forms of data (making the language more readable) –example, a programmer writes four sort subprograms where each operates on a different type of array – array of ints, array of longs, array of floats, array of Strings –the sort functions are all called using the same notation: sort(a, n); but the specific code executed depends on what type of array a is C#, C++, Java, Ada, Common Lisp have overloaded subprogs

15 Generic Subprograms Generic subprograms go beyond the overloaded subprogram by allowing the programmer to write one set of code that can operate on different types This provides a form of polymorphism –in Ada, you declare a subprogram to be generic and declare the type of data as, you then generate specific instances of the subprogram by writing further subprogram headers which specify the types for any placeholders the Ada compiler then generates a version of each of these subprogram headers see the example on page 423-424 –in C++, these are templates defined on classes where you specify and use name as a placeholder throughout your function unlike Ada, the compiler sets a template, not specific functions, and specific functions are generated at run-time as needed based on the type of parameter that was passed to the function –Java generic methods are much like C++’s but are more flexible in that wildcard types can be specified –C# is like Java except that wildcards are not allowed Dynamically bound languages (Common Lisp, APL) do not have typed variables, so all subprograms are generic

16 Other Topics Functions –are side effects allowed? not allowed in Ada –what types of values can be returned? C/C++/Java/C# allow any type to be returned FORTRAN 77, Pascal, Modula-2, Ada functions allow only primitive types (no structures) User-overloaded operators –available in Ada, Python, Ruby and C++ these functions are defined just like any function except that the name is an operator such as int operator * (…) to define * to be used say on vectors too much of this is not a good thing as it can harm readability Co-routines –special kind of subprogram that is used to implement concurrency concurrency is covered in chapter 13 Macros –most languages now have facilities for defining macros to be expanded to generate code, introduced in COBOL and extensively used in Lisp


Download ppt "Subprograms Support process abstraction and modularity –characteristics of subprograms are that they have a single entry point the calling entity is suspended."

Similar presentations


Ads by Google