Type checking is the process of checking and enforcing the constraints of types assigned to values in a program. A compiler has to check that a source program conforms both to the syntactic and semantic rules of the language as well as its type rules. The process also helps in limiting the kinds of types that can be used in certain contexts, assigning types to values, and then checking that these values are used appropriately.
Object types are checked by the type checker - a separate module in the compiler, which flags type errors when a value is being used in an inappropriate manner or the type rules of that type are being violated. The type checker reports a type error in such cases, and then the programmer must fix the wrong types. Whichever compiler is used for compilation, the type rules for a language must be enforced.
What is Type Checking?
Type checking is the process of verifying that the types of all variables, expressions, and functions are according to the rules of the programming language. It means operations operate on compatible data types, which helps in preventing errors and hence ensures correctness of the program. Type checking might be performed at compile time, called static type checking, or it could be performed during execution, and this is termed dynamic type checking. Both techniques have different advantages concerning error detection and flexibility of programs.
Every programming language has a collection of type rules that dictate how integers, floats, and characters can legally be used. A compiler keeps track of this type information and performs a set of computations to verify that a program is correct with respect to the type rules. Type checking therefore offers a guarantee that programs are type-safe and compatible with the language specifications.
Conversion
Conversion from one type to another type is known as implicit if it is to be done automatically by the compiler. Implicit type conversions are also called Coercion and coercion is limited in many languages.
Example: An integer may be converted to a real but real is not converted to an integer.
Conversion is said to be Explicit if the programmer writes something to do the Conversion.
Tasks
- Has to allow "Indexing is only on an array"
- Has to check the range of data types used
- INTEGER (int) has a range of -32,768 to +32767
- FLOAT has a range of 1.2E-38 to 3.4E+38
Types of Type Checking
There are two kinds of type checking:
- Static Type Checking.
- Dynamic Type Checking.
Static Type Checking
Static type checking is defined as type checking performed at compile time. It checks the type variables at compile-time, which means the type of the variable is known at the compile time. It generally examines the program text during the translation of the program. Using the type rules of a system, a compiler can infer from the source text that a function (fun) will be applied to an operand (a) of the right type each time the expression fun(a) is evaluated.
Examples of Static Checks
- Type-checks: A compiler should report an error if an operator is applied to an incompatible operand. For example, if an array variable and function variable are added together.
- The flow of control checks: Statements that cause the flow of control to leave a construct must have someplace to which to transfer the flow of control. For example, a break statement in C causes control to leave the smallest enclosing while, for, or switch statement, an error occurs if such an enclosing statement does not exist.
- Uniqueness checks: There are situations in which an object must be defined only once. For example, in Pascal an identifier must be declared uniquely, labels in a case statement must be distinct, and else a statement in a scalar type may not be represented.
- Name-related checks: Sometimes the same name may appear two or more times. For example in Ada, a loop may have a name that appears at the beginning and end of the construct. The compiler must check that the same name is used at both places.
Benefits of Static Type Checking
- Runtime Error Protection.
- It catches syntactic errors like spurious words or extra punctuation.
- It catches wrong names like Math and Predefined Naming.
- Detects incorrect argument types.
- It catches the wrong number of arguments.
- It catches wrong return types, like return "70", from a function that's declared to return an int.
Dynamic Type Checking
Dynamic Type Checking is defined as the type checking being done at run time. In Dynamic Type Checking, types are associated with values, not variables. Implementations of dynamically type-checked languages runtime objects are generally associated with each other through a type tag, which is a reference to a type containing its type information. Dynamic typing is more flexible. A static type system always restricts what can be conveniently expressed. Dynamic typing results in more compact programs since it is more flexible and does not require types to be spelled out. Programming with a static type system often requires more design and implementation effort.
Languages like Pascal and C have static type checking. Type checking is used to check the correctness of the program before its execution. The main purpose of type-checking is to check the correctness and data type assignments and type-casting of the data types, whether it is syntactically correct or not before their execution.
Static Type-Checking is also used to determine the amount of memory needed to store the variable.
Design of the type-checker depends on
- Syntactic Structure of language constructs.
- The Expressions of languages.
- The rules for assigning types to constructs (semantic rules).
The Position of the Type checker in the Compiler

The token streams from the lexical analyzer are passed to the PARSER. The PARSER will generate a syntax tree. When a program (source code) is converted into a syntax tree, the type-checker plays a Crucial Role. So, by seeing the syntax tree, you can tell whether each data type is handling the correct variable or not. The Type-Checker will check and if any modifications are present, then it will modify. It produces a syntax tree, and after that, INTERMEDIATE CODE Generation is done.
Overloading
An Overloading symbol is one that has different operations depending on its context.
Types of Overloading
Operator Overloading
In Mathematics, the arithmetic expression "x+y" has the addition operator '+' is overloaded because '+' in "x+y" have different operators when 'x' and 'y' are integers, complex numbers, reals, and Matrices.
Example: In Ada, the parentheses '()' are overloaded, the ith element of the expression A(i) of an Array A has a different meaning such as a 'call to function 'A' with argument 'i' or an explicit conversion of expression i to type 'A'. In most languages the arithmetic operators are overloaded.
Function Overloading
The Type Checker resolves the Function Overloading based on types of arguments and Numbers.
Example:
E-->E1(E2)
{
E.type:= if E2.type = s
E1.type = s -->t then t
else type_error
}Conclusion
Type checking is the process by which the compiler ensures that a program is types-safe, with the program adhering to all specifications put forward by the language definition. Static type checking, therefore, occurs at compile time and offers safety and reduced runtime errors. Dynamic type checking offers flexibility that allows developers to write compact and flexible code. Both are an integral part of how programming languages have been designed and function; thus, both guarantee that during execution, the code behaves exactly as it was intended to.