Why do so many use pointers to ROOT objects?

Whenever I’m browsing around for sample ROOT code, it seems like standard practice to declare ROOT objects by reference:
TObject * object = new TObject();
as opposed to
TObject object;
and, also, to therefore call functions by reference rather than directly. Is there a rationale that I’m missing for this practice? Obviously, there are cases when it is advantageous to treat objects as references, but this practice seems to be the rule rather than the exception when it comes to ROOT.

Thanks!

I have to say I am very annoyed by this, as it leads to huge memory leaks, especially in the physicist’s low quality code.

I use objects whenever possible (that is almost always) in my ROOT code and it works just as well.

1 Like

Hi UltraBird,

I am a bit confused by what you mean with “references” since AFAIK the ROOT API hardly ever uses reference parameters (but pointers types instead, the only exceptions to that I can recall would be in RooFit).

While as a user I can feel your pain, you shouldn’t forget that important parts of the ROOT API evolved in a time where C++ didn’t even contain reference, let alone smart pointer types. Also ROOT tends to heavily rely on CINT for parsing declarations, with CINT being evolved from a C interpreter, and CINT only supporting a limited subset of C++ (e.g. limited/unreliable support for modern template-heavy standard library/TR1 constructs) – this will change dramatically with cling BTW. So what you see in the ROOT API often has a strong C-with-classes feel to it, both due to historic and technical reasons.

As for additional rationales I could think of a couple of related ones:

  • in ROOT many objects are shared between scopes (e.g. their lifetimes are automatically managed by TDirectory and friends), and using old-school automatically managed objects can interfere with that.
  • before C++11 copies could potentially be very expensive, while passing pointers incurs just a copy of some int and dereference operations. This allows an I/O system with good performance.

In modern C++ there are good abstractions for lifetime management and I personally think updating the ROOT API in that domain would be a very good idea, but in the meantime there really isn’t much that keeps you personally from using automatically managed objects or smart pointer types in your code interfacing with the ROOT API (there are some gotchas, OK). People new to C++ and learning from ROOT examples will still have a hard time though.

Well, because people need objects and not functions? (hint - your second declaration is a function declaration :slight_smile: )

In general - not all object can be created on a stack, a lot of object should live longer than function execution time (so, live after function completed). In a modern C++ people usually use RAII idiom (smart pointers, etc.) instead of raw pointer (and this seriously improves the quality of C++ code BTW).
But in case of CINT (and potential problems with smart pointer and other template-based things) people use “good old” pointers.

In general, the answer is - you create something in dynamic memory (using new expressions) only if you really need it to be in dynamic memory.

I have noticed this as well, and decided that my own code would use less pointers and manual memory management. I generally just see extraneous pointers when I’ve incorporated some code fragments that I don’t really understand from ROOT Talk or the documentation. Other than some performance issues from over-copying objects passed into functions and such, I haven’t noticed any problems.

Jean-François

[quote=“tpochep”]Well, because people need objects and not functions? (hint - your second declaration is a function declaration :slight_smile: )
[/quote]
Oops! That was just a typo, fixed now.