c++ reference variable is like …. in java?

Q: a c++ reference is like a ….. in java?
A: depends (but i'd say it's not like anything in java.)

A1: For a monolithic type like int or char, a c++ reference variable is like a Integer.java variable.  Assignment to the reference is like calling a setValue(), though Interger.java doesn't have setValue().

A2: For a class type like Trade, a c++ reference is like nothing in java. When you do refVar2.member3, the reference variable is just like a java variable, but what if you do

Trade & refVar = someTrade; //initialize
refVar2 = …//?

The java programmer falls off her chair — this would call the implicit op=

refVar2.operator=(….)
Advertisements

##Just what are(not) part of Architecture (too-late-to-change)

Dogfight – When you develop a dogfight jet over 30 years, you stick to your initial design. You try to build on the strengths of your design and protect the weaknesses. You don’t suddenly abandon your design and adopt your rival’s design because you would be years behind on that path. Software architecture is similar.

Anyone with a few years experience can specify an architecture in some details, but those decisions are flexible and could be modified later on, so they aren’t make-or-break decisions, though they could waste time.

Q1: what Features define a given architecture? I’m a fellow architect. If you must describe in 10 phrases your system architecture and provide maximum Insight, which 10 aspects would you focus on?

Q2: (another side of the same coin) What technical Decisions must be made early when creating a system from scratch?
Q2b: in other words, what design decisions will be expensive to change later? Why expensive?

Disclaimer — In this context, “later” means somewhere during those pre-UAT phases, not LATE into the release process. Obviously after release any config/DB/code change requires regression test and impact analysis, but that’s not our topic here.

A colleague of mine liked to discuss in terms of layering. In OO architecture, A layer consists of a bunch of similar classes (or interfaces) dedicated to a logically coherent high-level task. 2 interacting layers can exist in the same OS process or (less common but very critical) across processes. Intra-process layering basically means the 2 interacting classes (belonging to 2 layers) have well-defined responsibilities and a well-defined contract between, where one is always a Service-provider (“dependency”) to the service-consumer. Though popular among architects, I’m not sure these are the most important architectural features.

Here are my answers to the question “Is the decision costly to change later in SDLC?”

? anything in the wsdl/schema of a web service? yes if i’m not the only developer of this web service’s clients. A change would need these fellow programmers to change their code and test, test, test
? fundamental data constraints like “if this is positive then that must be non-null”? Yes because other developers would assume that and design code flows accordingly.
? database schema, the ER between a bunch of tables? Yes since it usually requires code change “upstairs”. DB schema is usually a Foundation layer, often designed up front.
? choose a DB vendor? yes if you happen to have truly skillful database developers in the team. They will use proprietary vendor extensions behind the manager’s back when the temptation is too strong. Such non-portable business logic will be expensive to re-implement in another database.
? use MOM or RPC-style communication? yes
? Serialization format? yes. “Later” means implementation effort wasted
? XML or binary or free text format? yes probably
? make a bunch of objects immutable/read-only/const? yes. Adding this feature later can be hard. Look into C++ literature.
? shared vs unshared cache? yes. effort is non-trivial
? What logic to put into SQL vs java/C#? sometimes No. You can change things later on, but usually wasting sizable implementation effort
? Choose programming language? Yes. Implementation effort wasted if switching late in the game.
? make a batch task re-runnable? yes. Adding this feature later on can be hard

? MVC (the highest-level design pattern there is)? well… yes, though you can adjust this design later on
? where to implement authentication, entitlement? Many say yes, but I feel no. Make the damn system work first, then worry about securing it. On fast-paced trading floor, Business usually can tolerate this feature being not so perfect. Business and upper management worry more about ….. You got it — Functionality.

? Which commercial(or free) product to choose? sometimes NO. You can use mysql or activemq and then change to commercial products. In fast projects, We can often delay this decision. Start coding without this particular commercial product.

? make a module thread safe? no, even though adding this feature can be hard
? how many staging tables? no
? choose a decorator/factor/singleton (or any of the classic) design pattern? no. They are usually too  low-level to be among the “10 architectural features”. I don’t know why a lot of architect interview questions hit this area.

c# abstract class – a few language rules

Common IV topic…

[j] abstract class with 0 abstract member is perfectly fine in c#/java. http://stackoverflow.com/questions/2999944/why-does-c-sharp-allow-abstract-class-with-no-abstract-members

[j] if you simply add “abstract” to an existing (concrete) class C, then compiler will no longer allow new C()  [1]

[j] abstract class C is perfectly free to define a ctor, but it can only be invoked from a subclass ctor, not by new C() 

[j] abstract sealed/final class? won’t compile.

[j] Interface methods are always public. Abstract methods in abstract class are not.

[j=100% identical to java]

PAC (Pure-Abstract Class) is an extremely useful technique in c++ but in c#/java, an obscure cousin of “interface”. Given an interface MyType source code, you could replace the word “interface” with “abstract class”. Now a subtype must Singly inherit from MyType as the single parent. I feel the only justification is future-proof i.e. enforce that subtypes don’t inherit from another non-interface. This is deliberate self-crippling or self-constraint, just like [1]

Another (obscure) way to get a PAC — remove all concrete methods from a regular class. Unlike an interface, such a PAC could have fields and protected abstract methods.

specializing class templates (C++) #1 rule

Say you have Account objects to put into a Sorter class template. Generic Sorter was written for built-in types and uses operator-less-than (the left-arrowhead) in compare(), sort(), search() etc. However, Account class offers this->compareBalance() method and you want to use it in Account sorter. One solution is template specialization. Specifically, a specialization of the Sorter class template.

So You provide a custom definition of method compare(). How about other Sorter methods? There’s nothing to change in them so can we somehow “default” them to the Generic Sorter template?

Answer — no. As soon as you specialize the Sorter template for Account, your specialized template is disconnected from the original Generic Sorter template. Umbilical cord is cut once and for all. As described on (lower) P859 [[c++primer]], You must re-implement every public method. This is the Rule #1 in template specialization.

That was a regular/standard specialization. How about a partial specialization? Same answer.

Q: is the so-called specialized template a true template or just a regular class?
A: template. Difference is clear to the compiler. Syntax is vastly different[1]. A fully specialized template ironically has no dummy type, but it is technically still a “template” for creating classes[2], just like a document template. Only when you Instantiate the template with Account type, does the compiler actually create the real class. When given an Account type, the compiler will choose the specialized template over the generic or “default” template.

Here’s the paradox — in normal circumstances, a “document template” is meaningful when some section has dummy content. For example, a report template would have a dummy date, dummy author, dummy intro/summary, and dummy title. In a fully specialized template though, there’s nothing dummy, so is it a meaningful template? However, compiler still treats it technically as a template not a real class.

A partial specialization is like a report template with the dummy author replaced with a real author “hard-coded”. It is still meaningful as a template since it has *some* dummy content.

[1] template class Sorter {/*…*/} ; //note the syntax – template before the empty diamond
 no such thing when you instantiate a template. You instantiate a template simply in a variable declaration !
[2] though a fully specialized template can create no more than one class !

input iterator #& other iterator categories

(It’s probably enough to know when to use each. Internals may be muirky, undocumented and trivial…)

Note many of these categories are fake types and mean nothing to the compiler. Compiler knows classes, typedef, pointers … 
Note some of these categories are real types, some are characteristics of a given iterator object….

output iterator vs the outstream? See P5 [[eff STL]]

(see other post for const vs input iterators)

* input iterator is “Rw” iterator ie must let clients read container, may let clients write to container.
* const iterator is R~W iterator as it blocks write-access.
* output iterator is “rW” iterator — it may let clients read container
– many iterator classes [1] are “input-AND-output iterators” ie RW iterators ==> must let clients read and let clients write to container

When you see InputIterator in a template, remember input iterator is (not a type but) a family of types. I guess it could be fake type.

I guess you can visualize each iterator having these 2 groups of boolean flags. First group:
+ R or r
+ W or w or ~W (3 values)
+ const or mutable
++ const is actually part of declarations. const means “unwrapped iterator as lval won’t compile” [2]

And 2nd group:
+ F or ~F — forward or no-forward ie forward move unsupported
+ V or ~V — reverse or no-reverse
+ A or ~A — random or no-random

Between the 2 groups, there’s fairly good orthogonality. Within a group however, flags are not really independent
$ const ~W
$ const => R
$ A => F and V flags both set

[1] vector::iterator, but not vector::const_iterator
[2]
for(list::const_iterator myIt=myList.begin(); myIt!=myList.end(); myIt++){
*myIt += 10; // won’t compile with the const_ prefix
}

When reading function signatures, you will encounter a lot of different iterators, each having these flags. To simplify things, it’s best to focus on one group of flags at a time. Examples:

T a[n] can produce a qq(const T* ) iterator. First, this is a const R ~W. Secondly, it’s A F V

perl bless, briefly

2nd argument to bless is a …. well, a classname and also a package name. Whatever string you put there must be a valid package name (or the current package’s name if omitted). That package name is interpreted as a classname. The new object becomes an instance of that class. “The new object is blessed INTO the class”, as they like to say.

This 2nd argument is fundamental to constructor-inheritance. See P318 [[ programming perl ]]

The referent is often an empty hash. In other words, the reference to bless often points to an empty hash.

In Perl lingo, you can bless a referent or bless a reference, and everyone knows what you mean — no confusion.

Q: why do we need bless when a referent is already a chunk of memory
%%A: a bare reference can’t invoke a method. No inheritance of methods

car racing while holding coffee

I now recall that my manager (Yang?) mentioned (in my first performance review?) that I had a tendency to be tense and look worried, and improved a year later. Now I slowly understand why.

Now I think many people in finance IT have a lower standard on test “coverage”, bugs, code consistency, code smell…

For a few years in GS I felt like a heart surgeon — any (avoidable) logical bug would cost lives, and put me to jail for negligence of professional duty. Finance app development is like car racing while holding a cup of coffee. I was too scared of spillage but still had to drive as fast as others – so tense!

Now I know many colleagues design code less rigorously than I feel done elsewhere, and cover only the realistic use cases. If input is unexpected or erroneous, then damn it — “undefined behaviour”. That’s what I see in some quant library too. Subtle errors could sometimes spread like cancer undetected.

We relied on recon or other system’s validation to detect (preventable) bad data created by our engine.
Rather than “stop error propagation at the earliest”, we rely on downstreams.

Another reason — GS was my first job on Wall St. I struggled to break into Wall St and I didn’t want to be inadequate and lose self-confidence.

smart pointer casts – using shared_ptr for illustration

Smart pointers are the infrastructure of infrastructures for a quant library.

Minor performance issues become performance critical in this foundation component. One example is the allocation of the reference count. Another example is the concurrent update of the reference count. But here my focus is yet another performance issue — the lowly pointer-cast. (I don’t remember why performance is a problem … but I believe it is.)

C++ support 4 specific casts but smart pointers need to -efficiently- implement const_cast and dynamic_cast, in addition to the implicit upcast.

Q1: why can’t I assign a smartPtr-of-int instance to a variable declared as smartPtr of Dog?
A: compiler remembers the type of each pointer variable.

Q2: in that case, should c++ compiler allow me to assign a SP-of-Derived instance to a variable declared as SP of Base?
%%A: I don’t think so. I don’t think every smart pointer automatically supports upcast, but boost shared_ptr does, by design. See below.

For Boost, a Barcap expert said there’s an implicit cast from shared_ptr of T (RHS) to (LHS) shared_ptr of const T. See the special casting methods in http://www.boost.org/doc/libs/1_48_0/libs/smart_ptr/shared_ptr.htm

Specifically, boost says shared_ptr can be implicitly converted to shared_ptr whenever T* can be implicitly converted to U*. This mimics the behavior of raw pointers. In particular, shared_ptr is implicitly convertible to shared_ptr (i.e. add constness), to shared_ptr where U is an public/protected base of T (i.e. upcast), and to shared_ptr.I believe this is the same “member template” magic in the smart pointer chapter of [[more effC++]]

Allow me to explain the basics — in basic C++, a raw-ptr-to-T instance can be assigned to these variables —
T const *  my_ptr_to_const_T;
U * my_ptr_to_a_T_parent_class_U;
void * my_ptr_to_void;

Therefore a raw ptr supports these 3 (among others) casts implicitly. So does shared_ptr.

c++ method hiding, redefining, overriding – fundamentals

Background — When reading a particular function call in the context of a c++ class hierarchy, we need to identify exactly which function is selected at compile/runtime. In the case of “No match”, we get a compile-time error (never run time?).

Non-trivial. It’s easy to lose focus. Focus on the fundamental principles — only a few.

– Fundamental — override is strict [1]. If overriding, then vtbl dynamic binding. Simple and clear. Otherwise, it’s always, always static binding.
– Fundamental — if static binding, then remember the hiding rule. Per-name basis — See [[Eff C++] last item. As a result, some base class methods become unavailable — compiler errors. [3]
– Fundamental — compiler attempts implicit type conversion on every argument.

Redefining is an important special case of hiding, but fundamentally, it’s plain vanilla function hiding.

It was said that Overriding resolution is done “after” hiding? Does it mean that the hiding rules kick in first before system goes through overriding resolution? But I don’t think hiding would kick in at all.

[1] see http://bigblog.tanbin.com/2011/02/runtime-binding-is-highly-restrictive.html
[3] Fixable with a local “using” directive — Using Defeats Hiding