Study of C++
Explicit Memory Model
Both C and C++ have an explicit memory model which exposes the pointer structure to the programmer:- variables that are not pointers are either global or on the stack, and can be accessed without going through a reference of a memory location -- fast
- can take the addess-of (&) one of these variables to conjure a pointer to it;
- arrays can access data out of their bounds;
- dynamic allocation via
mallocallocates space on a heap and returns a pointer to it; it must be manuallyfree'd. - pointers that have what they point to may have been deallocated and reused by someone else by mistake
- deallocation can occur both by explicit
freeof heap data and by implicit deallocation of stack data upon return from a function call (even though there still may be a pointer to the datum)
- Explicit memory accounts for a good fraction of the bugs in C/C++ programs.
- Most more recent languages (Java, Ruby, Python, OCaml, etc) use an
implicit memory model to avoid these bugs
-- Implicit memory has no ability to take address-of, memory allocation is implicit, and memory is implicitly freed by a garbage collector - But code can be less efficient with an implicit memory since one more memory access is often needed when accessing the contents
- But but compilers keep getting better and are slowly closing the gap
- But but but low-level systems programs such as operating systems kernels and device drivers need the explicit memory model so there will always be a need for some explicit memory
Multiple Inheritance - the fantastic and the horrible
- Multiple inheritance is great: it simultaneously gives you
- Interfaces for free: an interface is an abstract class will null methods.
- A form of Mixin
classes
- (mixins are an idea originating in CLOS, the Common Lisp Object System)
- The major technical hiccup is The Diamond Problem. Blech! We will briefly review the C++ solutions to this problem, including virtual inheritance.
- In our
FbSRencoding of objects, recall that we explicitly inherited by grabbing methods out of our "superclass object"; using this approach we could easily make two or more "superclass objects" and then explicitly pick which one we are inheriting a method from, meaning no diamond ambiguity will arise. However there will be two copies of the "top" class in a diamond which may cause anomolous behavior.
Dynamic Typing in C++: RTTI
RTTI is RunTime Type Infomation.- This is a simple concept, objects carry their originating class names around at runtime.
- (Recall that declared types and runtime types may differ in languages with subtyping: the static type there means "this type or a subclass / implementing class")
- In Java this always happens due to its need to ensure safety of downcasts (raise an exception if they are bad).
- The downside is there is extra runtime overhead on adding this information to objects.
- In C++ the runtime type information is only added by the compiler if you need it (you are using RTTI on that object).
Templates
- The C++ answer to parametric polyorphism / generics
- Templates look something like parametric polymorphism but in fact are a completely different beast - they are more like macros
- Templates are all instantiated by a preprocessor at compile-time with the actual types, and that expanded code is what is compiled
- There is no need for the fancy bounded subtyping of Java - just instantiate and compile; the final code may have a type error due to a subtyping error
- The latter point makes it hard to debug type errors in templates -- you need to explicitly think about staged compilation (see below) to understand what the compiler is doing!
- But, Java generics get really complicated as well due to all of the sub-sub-sub cases and various needed extensions.
- Here is a cool example of how mixins can be done with single inheritance but with templates: Mixin classes in C++
Template Metaprogramming
Template metaprogramming in C++ is part of a larger topic: staged computation.- Partial evaluation: evaluate some of the program code at compile time, e.g. apply functions if (enough) arguments are known at compile-time. This is a whole subfield of research.
- MetaML
is a cleaner and more general notion than C++ template
metaprogramming - code is first-class, can
be combined almost like strings, but in a well-typed way.
- Run the first stage, which can do arbitrary computations; the result returned is the second-stage program.
- run the second stage, returning third stage program.
- etc - run until the final program results.
- ... then run that to do the actual application task.
- In terms of this model, C++ template metaprogramming is a 2-stage process.
- Also the default is reversed: unlabelled C++ code is analogous to the <bracketed> code in MetaML since its running is delayed.
Template Specialization
- Another handy feature of templates, it allows implementations to be specialized at instantiation time.
- Template specialization is somewhat similar to Java overloading - different versions for different types
- an example.
C++ Overloading
The overloading debate is longstanding.- Overloading is great: such compact syntax with such great power!
- Overloading is horrible: I have no idea which operators were overloaded where so I don't know what the heck this program is doing!
"How many handy dandy special cases should be supported by FaveLang?"
- LOTS! - but, now you have to worry about all of the contentious overlap between fancy feature 12 and fancy feature 41...
- LITTLE! - but, now you have to write more code for various patterns, over and over and over...