0% found this document useful (0 votes)
105 views

Unit 3 - Principles of Programming Languages

The document discusses subprogram characteristics and parameter passing methods in programming languages. It describes that a subprogram has a single entry point, control returns to the caller when execution terminates, and only one subprogram executes at a time. It then discusses parameter passing methods including pass-by-value, pass-by-result, and pass-by-reference and their advantages. Design issues for subprograms are outlined such as parameter type checking, local variable scope, and overloading.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
105 views

Unit 3 - Principles of Programming Languages

The document discusses subprogram characteristics and parameter passing methods in programming languages. It describes that a subprogram has a single entry point, control returns to the caller when execution terminates, and only one subprogram executes at a time. It then discusses parameter passing methods including pass-by-value, pass-by-result, and pass-by-reference and their advantages. Design issues for subprograms are outlined such as parameter type checking, local variable scope, and overloading.
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 12

Unit-3

General Subprogram Characteristics

i. Each subprogram has a single entry point.


ii. The calling program unit is suspended during the execution of the called subprogram, which implies
that there is only one subprogram in execution at any given time.
iii. Control always returns to the caller when the subprogram execution terminates.
Although FORTRAN subprograms can have multiple entries, that particular kind of entry is relatively
unimportant because it doesn’t provide any fundamentally different capabilities. Other alternatives to the
above assumptions results in co routines and concurrent units.
Basic Definitions
A subprogram definition describes the actions of the subprograms abstraction. It is the explicit request that
the subprogram be executed. It said to be active if, after having been called, it has begun execution but has
not yet completed that execution.
A subprogram header, which is the first line of the definition, serves several purposes. First, specifies
that the following syntactic unit is a subprogram definition of some particular kind. This specification is often
accomplished with a special word. Second, it provides a name for the subprogram. Third, it may optionally
specify a list of parameters. A subprogram header can itself serve as subprogram declaration.
SUBROUTINES ADDER (parameters)
This is the header of a FORTRAN subroutine subprogram named ADDER. In ADA, the header for ADDER would
be
procedure ADDER (parameters)
No special word appears in the header of a C subprograms. C has only one kind of subprogram, the function,
and the header of a function is recognized by context rather than by a special word. For example,
adder (parameters)
would serve as the header of a function named adder.
The parameters profile of a subprogram is the number, order, and types of its formal parameters. The
protocol of a subprogram is its parameter profile plus, if it is a function, its return type. In languages in which
subprograms have types, those types are defined by the subprogram’s protocol.
Subprograms can have declarations as well as definitions. This parallels the variable declarations and
definitions in C, in which the declarations are used to provide type information but not to define variables.
They are necessary when a variable must be referenced before the compiler has seen its definition.
Subprogram declarations provide interface information, which is primarily parameters types, but do not
include subprogram bodies. They are necessary when the compiler must translate a call to a subprogram
before it has seen that subprogram’s definition. In both the cases of variables and subprograms, declarations
are needed for static type checking. Subprogram declarations are common in C programs, where they are
called prototypes. They are also used in ADA and Pascal, where they are sometimes called forward or external
declarations.
1. Int cube(int); // prototype
2. Int main(){
3. Int y=5; //actual parameters
4. Cout<<cube(y); //Subprogram call
5. Int x=3;
6. Int cube (int x); //subprogram header

7. { // in line 6 int x is formal parameter


8. return x*x;
9. }
10. }

Scope and Lifetime of a variable


Scope – The scope of any variable is actually a subset of life time. A variable may be in the memory but may
not be accessible though. So, the area of our program where we can actually access our entity (variable in this
case) is the scope of that variable.
The scope of any variable can be broadly categorized into three categories :
Global scope : When variable is defined outside all functions. It is then available to all the functions of the
program and all the blocks program contains.
Local scope : When variable is defined inside a function or a block, then it is locally accessible within the block
and hence it is a local variable.
Function scope : When variable is passed as formal arguments, it is said to have function scope.
Life Time – Life time of any variable is the time for which the particular variable outlives in memory during
running of the program.
Static: A static variable is stored in the data segment of the "object file" of a program. Its lifetime is the entire
duration of the program's execution.
Automatic: An automatic variable has a lifetime that begins when program execution enters the function or
statement block or compound and ends when execution leaves the block. Automatic variables are stored in a
"function call stack".
Dynamic: The lifetime of a dynamic object begins when memory is allocated for the object (e.g., by a call to
malloc() or using new) and ends when memory is de-allocated (e.g., by a call to free() or using delete).
Dynamic objects are stored in "the heap".

Static and Dynamic Scope


Static Scoping: Static scoping is also called lexical scoping. In this scoping a variable always refers to its top
level environment. This is a property of the program text and unrelated to the run time call stack. Static
scoping also makes it much easier to make a modular code as programmer can figure out the scope just by
looking at the code. In contrast, dynamic scope requires the programmer to anticipate all possible dynamic
contexts.
In most of the programming languages including C, C++ and Java, variables are always statically (or lexically)
scoped i.e., binding of a variable can be determined by program text and is independent of the run-time
function call stack.
Example- A C Program to demonstrate static scoping.
#include<stdio.h>
int x = 10;
// Called by g()
int f()
{
return x;
}
// g() has its own variable
// named as x and calls f()
int g()
{
int x = 20;
return f();
}

int main()
{
printf("%d", g());
printf("\n");
return 0;
}
Output :
10

Dynamic Scoping: With dynamic scope, a global identifier refers to the identifier associated with the most
recent environment, and is uncommon in modern languages. In technical terms, this means that each
identifier has a global stack of bindings and the occurrence of a identifier is searched in the most recent
binding.
In simpler terms, in dynamic scoping the compiler first searches the current block and then successively all the
calling functions.
// Since dynamic scoping is very uncommon in
// the familiar languages, we consider the
// following pseudo code as our example. It
// prints 20 in a language that uses dynamic
// scoping.
int x = 10;
// Called by g()
int f()
{
return x;
}
// g() has its own variable
// named as x and calls f()
int g()
{
int x = 20;
return f();
}
main()

{
printf(g());
}
Output
20

Design Issues for Subprograms


1. What parameter passing Methods are Provided
2. Are parameter types checked?
3. Are local variables static or dynamic?
4. Can subprogram definitions appear in other program sub definition?
5. What is the referencing environment of a passed subprogram?
6. Can subprograms be overloaded?
7. Are subprograms allowed to be generic?

1. Parameter Passing Methods


Parameter passing methods are the ways in which parameters are transmitted to and/or from called
subprograms
Semantics Models of Parameter Passing
Formal parameters are characterized by one these distinct semantics models (1) They can receive data from
the corresponding actual parameter, (2) They can transmit data to the actual parameter (3) They can do both.
These three semantics models are called in mode, out mode, and inout mode, respectively. There are two
conceptual model of how data transfers take place in parameter transmission: Either an actual value is
physically moved (to the caller, to the callee, or both ways, and an access path is transmitted.
(i) pass-by-value (In-mode)
The value of the actual parameter is used to initialize the corresponding formal parameter. This formal
parameter is then used as a local variable in the subprogram. Since the subprogram is receiving data from the
actual parameter, this is a model of in-mode semantics. In most cases, pass-by-value is implemented using
copy when an actual value is copied then transmitted. However, it can be implemented by passing an access
path to the value of the actual parameter.
Advantage - Speed.
Example
#include <iostream.h>
int square (int x)
{
return x*x;
}
int main ( )
{
int num = 10;
int answer;
answer = square(num);
cout<<"Answer is "<<answer; // answer is 100
cout<<" Value of a is "<<num; // num will be 10
return 0;
}

ii. Pass by Result


With pass-by-result, no value is transmitted to the subprogram. Instead, the formal parameter acts like a local
variable, and before control is transferred back to the caller the variables value is transmitted back to the
actual parameter, because no data is transferred to the subprogram, but it transmits data back to the actual
parameter it is an out-mode semantic. Most typically pass-by-result uses a copy conceptual model.

iii. Pass-by-value-result
This passing method is actually a combination of pass-by-value and pass-by-result. The value of the actual
parameter is used to initialize the corresponding formal parameter, which then acts as a local variable. The
formal parameters must have local storage associated with the called subprogram. At termination, the
subprogram transmits the value of the formal parameter back to the actual parameter. As such, it uses in out-
mode semantics and copy passing conceptual model. Also, pass-by-value-result has the same advantages and
disadvantages as pass-by-value and pass-by-result with some more advantages. The largest extra advantage of
pass-by-value-result is that it solves pass-by-reference’s aliasing problems.

iv. Pass-by-reference
With pass-by-reference an address (reference to the memory location of the actual parameter) is passed to
the subprogram. It is another example of an inout-mode semantic.
Advantage- It is efficient in both time and space. This is no duplicate space required or copying.
Disadvantage – It increase the time to access formal parameters because of the additional level of indirect
addressing.
// Illustration of pass by reference
#include <iostream.h>
void square (int *x)
{
*x = (*x) * (*x);
}
int main ( )
{
int num = 10;
square(&num);
cout<<" Value of num is "<<num; // Value of num is 100
return 0;
}
As you can see the result will be that the value of a is 100. The idea is simple: the argument passed is the
address of the variable ‘num’. The parameter of ‘square’ function is a pointer pointing to type integer. The
address of ‘num’ is assigned to this pointer. You can analyze it as follows: &num is passed to int *x, therefore it
is the same as:
int *x = &num;
This means that ‘x’ is a pointer to an integer and has the address of the variable num.
Within the function we have: *x = (*x) * (*x);
* when used before a pointer will give the value stored at that particular address. Hence we find the product
of ‘num’ and store it in ‘num’ itself. i.e. the value of 100 is stored in the address of ‘num’ instead of 10 which
was originally present there. The diagram below illustrates the difference between pass by value and pass by
reference. Now when we dereference ‘x’ we are actually manipulating the value stored in ‘num’.

Difference between Pass by value and pass by reference


S.No Pass by Value Pass by Reference
1 Passes an argument by value. Passes an argument by reference.
2 Specifying the ByVal keyword. Specifying the ByRef keyword.
3 The procedure code does not have any access The procedure code gives a direct reference to the
to the underlying element in the calling code. programming element in the calling code.
4 In this, you are sending a copy of the data. In this, you are passing the memory address of the
data that is stored.
5 A change does not affect the actual value. Changes to the value effect the original data.

2. Type-Checking Parameters
It is now widely accepted that software reliability demands that the types of actual parameters be checked for
consistency with the types of the corresponding formal parameters.
Example
Result = sub1 (1)
 The actual parameter is an integer constant. If the formal parameter of sub1 is a floating-point type, no
error will be detected without parameter type checking.
 Early languages, such as Fortran 77 and the original version of C, did not require parameter type checking.
 Pascal, FORTRAN 90, Java, and ADA: it is always required
 Perl, PHP, and JavaScript do not have type checking.

3. Local Referencing Environments


 Variables that are defined inside subprograms are called local variables.
 Local variables can be either static or stack dynamic “bound to storage when the program begins
execution and are unbound when execution terminates.”
Advantages of using stack dynamic
a. Support for recursion.
b. Storage for locals is shared among some subprograms.
Disadvantages
a. Allocation/deallocation time.
b. Indirect addressing “only determined during execution.”
c. Subprograms cannot be history sensitive “can’t retain data values of local variables between calls.”
Advantages of using static variables
a. Static local variables can be accessed faster because there is no indirection.
b. No run-time overhead for allocation and deallocation.
c. Allow subprograms to be history sensitive.
Disadvantages:
a. Inability to support recursion.
b. Their storage can’t be shared with the local vars of other inactive Subprograms.
In C functions, locals are stack-dynamic unless specifically declared to be static.
Example
int adder(int list[ ], int listlen) {
static int sum = 0; //sum is static variable
int count; //count is stack-dynamic
for (count = 0; count < listlen; count++)
sum += list[count];
return sum;
}
Ada subprograms and the methods of C++, Java, and C# have only stack dynamic local variables.

4. Parameters that are Subprogram Names


 In languages that allow nested subprograms, such as JavaScript, there is another issue related to
subprogram names that are passed as parameters.
 The question is what referencing environment for executing the past subprogram should be used.
 The three choices are:
(i) It is the environment of the call statement that enacts the past subprogram “Shallow binding.”
(ii) It is the environment of the definition of the passed subprogram “Deep binding.”
(iii) It is the environment of the call statement that passed the subprogram as an actual parameter ”Ad
hoc binding; has never been used”
Example “written in the syntax of Java”
function sub1( ) {
var x;
function sub2( ) {
alert(x); // Creates a dialog box with the value of x
};
function sub3( ) {
var x;
x = 3;
sub4(sub2);
};
function sub4(subx ) {
var x;
x = 4;
subx( );
};
x = 1;
sub3( );
};
Shallow Binding: The referencing environment of that execution is that of sub4, so the reference to x in sub2
is bound to the local x in sub4, and the output of the program is 4.
Deep Binding: The referencing environment of sub2’s execution is that of sub1, so the reference so the
reference to x in sub2 is bound to the local x in sub1 and the output is 1.
Ad hoc: The binding is to the local x in sub3, and the output is 3.
Shallow binding is not appropriate for static-scoped languages with nested subprograms.

5. Overloaded Subprograms
 An overloaded operator is one that has multiple meanings. The types of its operands determine the
meaning of a particular instance of an overloaded operator.
 For example, if the * operator has two floating-point operands in a Java program, it specifies floating-
point multiplication.
 But if the same operator has two integer operands, it specifies integer multiplication.
 An overloaded subprogram is a subprogram that has the same name as another subprogram in the
same referencing environment.
 Every version of an overloaded subprogram must have a unique protocol; that is, it must be different
from the others in the number, order, or types of its parameters, or in its return if it is a function.
 The meaning of a call to an overloaded subprogram is determined by the actual parameter list.
 Users are also allowed to write multiple versions of subprograms with the same name in ADA, Java,
C++, and C#.
 Overloaded subprograms that have default parameters can lead to ambiguous subprogram calls.

Function Overloading
If any class has multiple functions with same names but different parameters then they are said to be
overloaded. Function overloading allows you to use the same name for different functions, to perform, either
same or different functions in the same class.

Function overloading is usually used to enhance the readability of the program. If you have to perform one
single operation but with different number or types of arguments, then you can simply overload the function.
Example - int sum (int x, int y)
{
cout<<x+y;
}

int sum(int x, int y, int z)


{
cout<<x+y+z;
}
Here sum() function is overloaded, to have two and three arguments. Which sum() function will be called,
depends on the number of arguments.
int main()
{
sum (10,20); // sum() with 2 parameter will be called
sum(10,20,30); //sum() with 3 parameter will be called
}
6.Generic Subprograms
 A programmer should not need to write four different sort subprograms to sort four
only in element type.
 A generic or polymorphic subprogram takes parameters of different types on different activations.
 Overloaded subprograms provide a particular kind of polymorphism called ad hoc polymorphism.
 Parametric polymorphism is provided by a subprogram that takes a generic parameter that is used in a
type expression that describes the types of the parameters of the subprogram.
Generic Functions in C++
 Generic functions in C++ have the descriptive name of template functions.
 The following is the C++ version of the generic sort subprogram.
Example
template <class Type>
void generic_sort (Type list [ ], int len) {
int top, bottom;
Type temp;
for (top = 0, top < len –2; top ++)
for (bottom = top + 1; bottom < len – 1; bottom++)
if (list [top] > list [bottom]) {
temp = list [top];
list[top] = list[bottom];
} // end for bottom
} // end for generic
The instantiation of this template function is:
float flt_list [100];

generic_sort (flt_list, 100);
Example : Function Template to find the largest number
Program to display largest among two numbers using function templates.
// If two characters are passed to function template, character with larger ASCII value is displayed.
#include <iostream>
using namespace std;
// template function
template <class T>
T Large(T n1, T n2)
{
return (n1 > n2) ? n1 : n2;
}
int main()
{ int i1, i2;
float f1, f2;
char c1, c2;
cout << "Enter two integers:\n";
cin >> i1 >> i2;
cout << Large(i1, i2) <<" is larger." << endl;

cout << "\nEnter two floating-point numbers:\n";


cin >> f1 >> f2;
cout << Large(f1, f2) <<" is larger." << endl;
cout << "\nEnter two characters:\n";
cin >> c1 >> c2;
cout << Large(c1, c2) << " has larger ASCII value.";
return 0;
}
Output
Enter two integers:
5 10
10 is larger.
Enter two floating-point numbers:
12.4 10.2
12.4 is larger.

Design Issues for Functions


The two design issues specific to functions are
1. Functions Side effects (Are side effect allowed ?) :- To avoid the problem caused by functional side
effects, the parameters passed to functions should always be inmode. In ADA, functions can have only
inmode parameters. This avoids functional side effects caused because of its parameters or through
aliasing of parameters.
In most other languages, functions can have either pass by value or pass by reference parameters, thus
allowing functions that cause side effects and aliasing.
2. Types of returned value (What types of values can be returned ? ):- Many imperative languages
restrict the type that can be returned by their functions.
 FORTRAN 77, Pascal and Modula-2 functions allow only unstructured types to be returned.
 C allows any type to be returned by its functions except arrays and functions.
 C++ also allows any type to be returned by functions including class.

Co-routines
 A co-routine is a subprogram that has multiple entries and controls them itself
 Also called symmetric control: caller and called co-routines are on a more equal basis
 A co-routine call is named a resume
 The first resume of a co-routine is to its beginning, but subsequent calls enter at the point just after the
last executed statement in the co-routine
 Co-routines repeatedly resume each other, possibly forever
 Co-routines provide quasi-concurrent execution of program units (the co-routines); their execution is
interleaved, but not overlapped
A B

Resume

From master Resume B Resume A

Resume B Resume A

Fig-3.1 (a) Co-routine Proess

Co-routines Illustrated: Possible Execution Controls


A Resume B

From master

Resume B Resume A

Resume B Resume A

Fig-3.1 (b) Co-routine Possible Execution Controls

Co-routines Illustrated: Possible Execution Controls with Loops


A B
Resume

First resume

Resume B

Resume A

subsquent resume

Fig-3.1 (c) Co-routine Possible Execution Controls with Loops

You might also like