Stack deallocation is automatic.
Heap deallocation is must be done explicitly by the programmer in C++; use delete.
Heap deallocation is implicit in Java; the garbage collector automatically frees allocated storage that is no longer reachable through program variables.
Pointers whose values come from executing new reference locations on the heap.
In C++ and Java object types are created on the heap using new.
In Java this is the only way to create object types.
In C++ object types can be created on the stack simply by declaring an object variable of the object type (not a pointer).
In C++, but not in Java, the address of operator, operator & can be used to get the address of an object created on the heap and assign it to a pointer variable.
If a pointer in C++ references an object on the stack, delete should NOT be used, since stack objects are deallocated automatically and delete expects only pointers into the heap.
When an exceptions is thrown or raised, it behaves
What is the rule for binding a thrown exception to an exception handler? Is it a static rule or a dynamic rule?
C++ doesn't have checked exceptions.
Java distinguishes between checked and run-time (or unchecked) exceptions.
What does this mean?
run-time: ArrayIndexOutOfBoundsException checked: FileNotFoundException
1 public class ExceptionScope { 2 public static void main(String[] args) { 3 new Outer().run(); 4 } 5 } 6 7 class X extends RuntimeException {} 8 9 class Outer { 10 void run() { 11 try { 12 class Inner { 13 void foo() { 14 throw new X(); 15 } 16 void bar() { 17 try { 18 foo(); 19 } catch (X e) { 20 System.out.println("bar"); 21 } 22 } 23 } 24 new Inner().bar(); 25 } catch (X e) { 26 System.out.println("run"); 27 } 28 } 29 }
A C++ function can be declared to specify what exceptions it might throw.
int get(int k) throw(out_of_range) { ... // may throw out_of_range }
Another big difference between Java and C++:
1 int get(int k) throw(out_of_range) 2 { 3 if ( k < 0 || k >= maxsize) { 4 throw out_of_range("Invalid index!"); 5 } 6 return a[k]; 7 } In Java, line 4 should be something like throw new ArrayIndexOutOfBoundsException("Invalid index!"); So in Java the exception object is created on the heap. In C++ a handler can declare its parameter to be passed to it by reference or by value just like any other function! Where is the exception object created in C++?
Here is what Stroustroup says about memory for exception objects that are thrown:
In principle, an exception is copied when it is thrown, so the handler gets hold of a copy of the original exception. In fact, an exception may be copied several times before it is caught. Consequently, we cannot throw and exception that cannot be copied.
Bjarne Stroustruop,The C++ Programming Language Third Edition, page 362.
So even if a handler declares its parameter to be passed by reference, it may be a reference to a copy of the exception that was thrown.
Questions for the compiler implementer are (a) where is this copy allocated? and (b) when is the copy deallocated?
Weakest: One type for all values.
Strongest: Type of value exactly identifies the legal operations on that value.
Perl's type system is weaker than C++'s.
A type-safe language is one for which all type errors are detected either at compile time or at run-time.
(A type-safe language is also called a strongly typed language, but I prefer type-safe. One can then talk about both properties
Dynamically: Perl (some features of OO languages; e.g., Java, C++)
Statically: C++, Java, ML
In many languages, some types are considered subtypes of others.
If T is a subtype of U then we can use a T expression anywhere a U expression is allowed.
For example,
1 void print(Object obj) { 2 int n = obj.hashCode(); 3 } 4 5 print( new String("Hello")); 6 print( new Integer(5)); Both Integer and String are subtypes of Object. So either type can be passed to print and used at line 2.
A monomorphic type is one that permits variables declared of that type to only hold values of one type.
Examples are int, float, double in Java or C++
A polymorphic type is a type that permits variables declared of that type to hold values from some set or family of 2 or more types.
Recursive types refer to themselves in their definition.
For C++, this typically only works if the self reference is to a pointer to the type:
class node { public: int data; node * next; node * prev; ... }; public class node { public int data; public node next; // But all non-primitive types are references public node prev; // in Java. ... }
Assembly languages: these are typeless.
Types: Types support data abstraction and higher level programming
Examples: basic types, arrays, records, pointers, references.
Memory management: stack vs. heap
Problems: pointers into stack, pointer arithmetic, and heap deallocation can cause type errors. References are generally safer as they don't provide these operations.
Next...