Types - PowerPoint PPT Presentation

About This Presentation
Title:

Types

Description:

A type limit the set of operations that may be performed on a value belonging to ... Note that the upcast can be verified at compile time whereas the downcast cannot ... – PowerPoint PPT presentation

Number of Views:57
Avg rating:3.0/5.0
Slides: 48
Provided by: medialab
Category:
Tags: types | upcast

less

Transcript and Presenter's Notes

Title: Types


1
Types
  • Antonio Cisternino
  • Programmazione Avanzata

2
Types
  • Computer hardware is capable of interpreting bits
    in memory in several different ways
  • A type limit the set of operations that may be
    performed on a value belonging to it
  • The hardware usually doesnt enforce the notion
    of type, though it provides operations for
    numbers and pointers
  • Programming languages tend to associate types to
    value to enforce error-checking

3
Type system
  • A type system consists of
  • A mechanism for defining types and associating
    them with certain language constructs
  • A set of rules for
  • type equivalence two values are the same
  • type compatibility a value of a given type can
    be used in a given context
  • type inference type of an expression given the
    type of its constituents

4
Type checking
  • Type checking is the process of ensuring that a
    program obeys the languages type compatibility
    rules
  • A language is strongly typed if it prohibits, in
    a way that the language implementation can
    enforce, the application of any operation to any
    object that is not intended to support that
    operation
  • A language is statically typed if it is strongly
    typed and type checking can be performed at
    compile time

5
Programming Languages and type checking
No type checking
  • Assembly
  • C
  • Pascal
  • C
  • Java
  • Lisp
  • Prolog
  • ML

Static type checking Not entirely strongly typed
(union, interoperability of pointers and arrays)
Static type checking Not entirely strongly typed
(untagged variant records)
Static type checking Not entirely strongly typed
(as C) Dynamic type checking (virtual methods)
Static type checking Dynamic type checking
(virtual methods, upcasting) Strongly typed
Dynamic type checking Strongly typed
Dynamic type checking Strongly typed
Static type checking Strongly typed
6
Different views for types
  • Denotational
  • types are set of values (domains)
  • Application semantics
  • Constructive
  • Built-in types
  • Composite types (application of type
    constructors)
  • Abstraction-based
  • Type is an interface consisting of a set of
    operations

7
Language types
  • Boolean
  • Int, long, float, double (signed/unsigned)
  • Characters (1 byte, 2 bytes)
  • Enumeration
  • Subrange (n1..n2)
  • Composite types
  • Struct
  • Union
  • Arrays
  • Pointers
  • List

8
Type Conversions and Casts
  • Consider the following definition
  • int add(int i, int j)
  • int add2(int i, double j)
  • And the following calls
  • add(2, 3) // Exact
  • add(2, (int)3.0) // Explicit cast
  • add2(2, 3) // Implicit cast

9
Memory Layout
  • Typically hardware-types on 32 bits architectures
    require from 1 to 8 bytes
  • Composite types are represented by chaining
    constituent values together
  • For performance reasons often compilers employ
    padding to align fields to 4 bytes addresses

10
Memory layout example
  • struct element
  • char name2
  • int atomic_number
  • double atomic_weight
  • char metallic

11
Optimizing Memory Layout
  • C requires that fields of struct should be
    displaced in the same order of the declaration
    (essential for working with pointers!)
  • Not all languages behaves like this for instance
    ML doesnt specify any order
  • If the compiler is free of reorganizing fields
    holes can be minimized (in the example by packing
    metallic with name saving 4 bytes)

12
Union
  • Union types allow sharing the same memory area
    among different types
  • The size of the value is the maximum of the
    constituents

union u struct element e int number
13
Abstract Data Types
  • According to the abstraction-based view of types
    a type is an interface
  • An ADT defines a set of values and the operations
    allowed on it
  • In their evolution programming languages have
    included mechanisms to define ADT
  • Definition of an ADT requires the ability of
    incapsulating values and operations

14
Example a C list
  • struct node
  • int val
  • struct list next
  • struct node next(struct node l) return
    l-gtnext
  • struct node initNode(struct node l, int v)
  • l-gtval v l-gtnext NULL return l
  • void append(struct node l, int v)
  • struct node p l
  • while (p-gtnext) p p-gtnext
  • p-gtnext
  • initNode((struct node)malloc(sizeof(struct
    node)), v)

15
ADT, modules and classes
  • C doesnt provide any mechanism to hide the
    structure of data types
  • A program can access the next pointer without
    using the next function.
  • The notion of module has been introduced to
    define data types and restrict the access to
    their definition
  • An evolution of module is the class values and
    operations are tied together (with the addition
    of inheritance)

16
Class type
  • Class is a type constructor like struct and array
  • A class combines other types like structs
  • Class definition contains also methods which are
    the operations allowed on the data
  • The inheritance relation is introduced
  • Two special operations provide control over
    initialization and finalization of objects

17
The Node Type in Java
  • class Node
  • int val
  • Node m_next
  • Node(int v) val v
  • Node next() return m_next
  • void append(int v)
  • Node n this
  • while (n.m_next ! null) n n.m_next
  • n.m_next new Node(v)

18
Inheritance
  • If the class A inherits from class B (AltB) when
    an object of class B is expected an object of
    class A can be used instead
  • Inheritance expresses the idea of adding features
    to an existing type (both methods and attributes)
  • Inheritance can be single or multiple

19
Example
  • class A
  • int i
  • int j
  • int foo() return i j
  • class B A
  • int k
  • int foo() return k super.foo()

20
Questions
  • Consider the following
  • A a new A()
  • A b new B()
  • Console.WriteLine(a.foo())
  • Console.WriteLine(b.foo())
  • Which version of foo is invoked in the second
    print?
  • What is the layout of class B?

21
Upcasting
  • Late binding happens because we convert a
    reference to an object of class B into a
    reference of its super-class A (upcasting)
  • B b new B()
  • A a b
  • The runtime should not convert the object only
    use the part inherited from A
  • This is different from the following implicit
    cast where the data is modified in the
    assignment
  • int i 10
  • long l i

22
Downcasting
  • Once we have a reference of the super-class we
    may want to convert it back
  • A a new B()
  • B b (B)a
  • During downcast it is necessary to explicitly
    indicate which class is the target a class may
    be the ancestor of many sub-classes
  • Again this transformation informs the compiler
    that the referenced object is of type B without
    changing the object in any way

23
Upcasting, downcasting
  • We have shown upcasting and downcasting as
    expressed in languages such as C, C and Java
    though the problem is common to OO languages
  • Note that the upcast can be verified at compile
    time whereas the downcast cannot
  • Upcasting and downcasting dont require runtime
    type checking
  • in Java casts are checked at runtime
  • C simply changes the interpretation of an
    expression at compile time without any attempt to
    check it at runtime

24
Late Binding
  • The output of the example depends on the
    language the second output may be the result of
    invoking Afoo() or Bfoo()
  • In Java the behavior would result in the
    invocation of Bfoo
  • In C Afoo would be invoked
  • The mechanism which associates the method
    Bfoo() to b.foo() is called late binding

25
Late Binding
  • In the example the compiler cannot determine
    statically the exact type of the object
    referenced by b because of upcasting
  • To allow the invocation of the method of the
    exact type rather than the one known at compile
    time it is necessary to pay an overhead at
    runtime
  • Programming languages allow the programmer to
    specify whether to apply late binding in a method
    invocation
  • In Java the keyword final is used to indicate
    that a method cannot be overridden in subclasses
    thus the JVM may avoid late binding
  • In C only methods declared as virtual are
    considered for late binding

26
Late Binding
  • With inheritance it is possible to treat objects
    in a generic way
  • The benefit is evident it is possible to write
    generic operations manipulating objects of types
    inheriting from a common ancestor
  • OOP languages usually support late binding of
    methods which method should be invoked is
    determined at runtime
  • This mechanism involves a small runtime overhead
    at runtime the type of an object should be
    determined in order to invoke its methods

27
Example (Java)
  • class A
  • final void foo()
  • void baz()
  • void bar()
  • class B extends A
  • // Suppose it possible!
  • final void foo()
  • void bar()
  • A a new A()
  • B b new B()
  • A c b
  • a.foo() // Afoo()
  • a.baz() // Abaz()
  • a.bar() // Abar()
  • b.foo() // Bfoo()
  • b.bar() // Bbar()
  • c.foo() // Afoo()
  • c.bar() // Bbar()

28
Abstract classes
  • Sometimes it is necessary to model a set S of
    objects which can be partitioned into subsets
    (A0, An) such that their union covers S
  • ?x ? S ? ?Ai ? S, x ? Ai
  • If we use classes to model each set it is natural
    that
  • ? A ? S, AltS
  • Each object is an instance of a subclass of S and
    no object is an instance of S.
  • S is useful because it abstracts the
    commonalities among its subclasses, allowing to
    express generic properties about its objects.

29
Example
  • We want to manipulate documents with different
    formats
  • The set of documents can be partitioned by type
    doc, pdf, txt, and so on
  • For each document type we introduce a class that
    inherits from a class Doc that represents the
    document
  • In the class Doc we may store common properties
    to all documents (title, location, )
  • Each class is responsible for reading the
    document content
  • It doesnt make sense to have an instance of Doc
    though it is useful to scan a list of documents
    to read

30
Abstract methods
  • Often when a class is abstract some of its
    methods could not be defined
  • Consider the method read() in the previous
    example
  • In class Doc there is no reasonable
    implementation for it
  • We leave it abstract so that through late binding
    the appropriate implementation will be called

31
Syntax
  • Abstract classes can be declared using the
    abstract keyword in Java or C
  • abstract class Doc
  • C assumes a class is abstract if it contains an
    abstract method
  • it is impossible to instantiate an abstract
    class, since it will lack that method
  • A virtual method is abstract in C if its
    definition is empty
  • virtual string Read() 0
  • In Java and C abstract methods are annotated
    with abstract and no body is provided
  • abstract String Read()

32
Inheritance
  • Inheritance is a relation among classes
  • Often systems impose some restriction on
    inheritance relation for convenience
  • We say that class A is an interface if all its
    members are abstract has no fields and may
    inherit only from one or more interfaces
  • Inheritance can be
  • Single (A lt B ? (?C. A lt C ? C B))
  • Mix-in (S B A lt B, ?1 B?S ? interface(B))
  • Multiple (no restriction)

33
Multiple inheritance
  • Why systems should impose restrictions on
    inheritance?
  • Multiple inheritance introduces both conceptual
    and implementation issues
  • The crucial problem, in its simplest form, is the
    following
  • B lt A ? C lt A
  • D lt B ? D lt C
  • In presence of a common ancestor
  • The instance part from A is shared between B and
    C
  • The instance part from A is duplicated
  • This situation is not infrequent in C
    iosgtistream, iosgtostream and iostreamltistream,
    iostreamltostream
  • The problem in sharing the ancestor A is that B
    and C may change the inherited state in a way
    that may lead to conflicts

34
Java and Mix-in inheritance
  • Both single and mix-in inheritance fix the common
    ancestor problem
  • Though single inheritance can be somewhat
    restrictive
  • Mix-in inheritance has become popular with Java
    and represents an intermediate solution
  • Classes are partitioned into two sets interfaces
    and normal classes
  • Interfaces constraints elements of the class to
    be only abstract methods no instance variables
    are allowed
  • A class inherits instance variables only from one
    of its ancestors avoiding the diamond problem of
    multiple inheritance

35
Implementing Single and Mix-in inheritance
  • Consists only in combining the state of a class
    and its super-classess

Note that Upcasting and Downcasting comes for
free the pointer at the base of the instance can
be seen both as a pointer to an instance of A or B
A
BltA
CltBltA
DltCltBltA
A
A
A
A
B
B
B
D
36
Implementing multiple inheritance
  • With multiple inheritance becomes more complex
    than reinterpreting a pointer!

A
BltA
CltA
DltB, DltC
DltB, DltC
A
A
A
A
A (B)
B
C
A (C)
B
C
B
D
C
D
37
Late binding
  • How to identify which method to invoke?
  • Solution use a v-table for each class that has
    polymorphic methods
  • Each virtual method is assigned a slot in the
    table pointing to the method code
  • Invoking the method involves looking up in the
    table at a specific offset to retrieve the
    address to use in the call instruction
  • Each instance holds a pointer to the v-table
  • Thus late binding incurs an overhead both in time
    (2 indirections) and space (one pointer per
    object)
  • The overhead is small and often worth the benefits

38
Late binding an example (Java)
As v-table
V-pointer
  • class A
  • void foo()
  • void f()
  • int ai
  • class B extends A
  • void foo()
  • void g()
  • int bi

foo
a
ai
f
b
Bs v-table
V-pointer
c
foo
ai
f
bi
g
B b new B() b.foo() b.g() b.f()
A a new A() a.foo() a.f()
A c b c.foo() c.f()
39
JVM invokevirtual
  • A call like
  • x.equals("test")
  • is translated into
  • aload_1 push local variable 1 (x) onto the
    operand stack
  • ldc "test" push string "test" onto the operand
    stack
  • invokevirtual java.lang.Object.equals(Ljava.lang.O
    bject)Z
  • where java.lang.Object.equals(Ljava.lang.Object)Z
    is a method specification
  • When invokevirtual is executed, the JVM looks at
    method specification and determines its of args
  • From the object reference it retrieves the class,
    searches the list of methods for one matching the
    method descriptor.
  • If not found, searches its superclass

40
Invokevirtual optimization
  • The Java compiler can arrange every subclass
    method table (mtable) in the same way as its
    superclass, ensuring that each method is located
    at the same offset
  • The bytecode can be modified after first
    execution, by replacing with
  • invokevirtual_quick mtable-offset
  • Even when called on objects of different types,
    the method offset will be the same

41
Virtual Method in Interface
  • Optimization does not work for interfaces
  • interface Incrementable public void incr()
  • class Counter implements Incrementable
  • public void incr()
  • class Timer implements Incrementable
  • public void decr()
  • public void inc()
  • Incrementable i
  • i.incr()
  • Compiler cannot guarantee that method incr() is
    at the same offset.

42
Runtime type information
  • Execution environments may use the v-table
    pointer as a mean of knowing the exact type of an
    object at runtime
  • This is what happens in C with RTTI, in .NET
    CLR and JVM
  • Thus the cost of having exact runtime type
    information is allocating the v-pointer to all
    objects
  • C leaves the choice to the programmer without
    RTTI no v-pointer is allocated in classes without
    virtual methods

43
Overloading
  • Overloading is the mechanism that a language may
    provide to bind more than one object to a name
  • Consider the following class
  • class A
  • void foo()
  • void foo(int i)
  • The name foo is overloaded and it identifies two
    methods

44
Method overloading
  • Overloading is mostly used for methods because
    the compiler may infer which version of the
    method should be invoked by looking at argument
    types
  • Behind the scenes the compiler generates a name
    for the method which includes the type of the
    signature (not the return type!)
  • This process is known as name mangling
  • In the previous example the name foo_v may be
    associated to the first method and foo_i to the
    second
  • When the method is invoked the compiler looks at
    the types of the arguments used in the call and
    chooses the appropriate version of the method
  • Sometimes implicit conversions may be involved
    and the resolution process may lead to more than
    one method in this case the call is considered
    ambiguous and a compilation error is raised

45
Operator overloading
  • Though operators such as and have a syntax
    different from the function invocation they
    identify functions
  • C and other languages (i.e. C) allow
    overloading these operators in the same way as
    ordinary functions and methods
  • Conceptually each invocation of is rewritten in
    to the functional version and the standard
    overloading process is used
  • Example (C)
  • c a b // operator(c, operator(a, b))

46
Late binding an example (Java)
As v-table
V-pointer
  • class A
  • void foo()
  • void f()
  • int ai
  • class B extends A
  • void foo(int i)
  • void g()
  • int bi

foo()
a
ai
f
b
Bs v-table
V-pointer
c
foo()
ai
f
bi
foo(int)
g
B b new B() b.foo() b.g() b.f()
A a new A() a.foo() a.f()
A c b c.foo(3) c.f()
47
Late binding only on first argument
As v-table
V-pointer
  • class A
  • void foo(A a)
  • void f()
  • int ai
  • class B extends A
  • void foo(B b)
  • void g()
  • int bi

foo()
a
ai
f
b
Bs v-table
V-pointer
c
foo(A)
ai
f
bi
foo(B)
g
B b new B() b.foo() b.g() b.f()
A a new A() a.foo() a.f()
A c b c.foo(c) c.f()
Write a Comment
User Comments (0)
About PowerShow.com