Using defaulted ctor on TObject derived classes?

From the below Pull Request on Github I learned that using = default; to create a defaulted ctor for TNamed introduces some issues. I have not fully understood those.

This confuses me somewhat:

If I create a normal user defined class that derives from TObject (I hope that’s generally okay?!), should I avoid using = default; on the default ctor?

If this is really the case: How can I check for the default ctor being valid in my unit tests? Is there some test helper function in ROOT that helps me check my default ctor?


ROOT Version: latest
Platform: any?
Compiler: any?


There is magic code in TObject constructor which allows us to distinguish
if object created with new operator or as stack variable. In first case
object should be cleaned up - via ROOT cleanup lists.

All this does not work if = default constructor is used.
Therefore all ROOT classes (especially graphics-related) do not use such constructors declaration.

For your particular case it depends if objects ownership handled properly.
Means you destroy it, add to TList with ownership flag and so on.
In such case you can use = default constructor.

Probably @pcanal can give better explanation.

1 Like

There is simple test:

auto obj = new MyType{}
if (! obj->IsOnHeap())
   throw "TObject::IsOnHeap is broken for MyType";
delete obj;
1 Like

Note:

There’s a new PR on ROOT to improve the documentation:

It’s also discussed, whether one can check for derived classes using this convention.

1 Like

(already asked here, but it seems more appropriate here.)

If I got this right, the IsOnHeap-behaviour depends on UB? And not allowing = default on derived classes to support this UB is at least unintuitive. (It’s good, that it’s documented, and it’s good to consider checking it!)

Are there any plans to phase out (and then deprecate) this? So that people actually can use = default?

The first step towards phasing out would be to document the issues involved when using = default and what a non-functional IsOnHeap would actually induce?

Hello @ctacke,
yes, unfortunately the behaviour relies on UB and it’s not easy to get rid of this - in fact, it is likely impossible without breaking lots of code depending on it. The plan for ROOT moving forward is to rely less on TObject and automatic memory management in general, especially in user-facing code.

Most of the newer interfaces, such as RDataFrame or RNTuple, don’t require users to interface to TObject and we plan for this to be the case for all cases where this is possible. However when it comes to interfacing with old code unfortunately this behavior needs to be accounted for.

1 Like

The major reason we use the IsOnHeap feature is to due to the implicit shared ownership. For example for this code to work:

TFile *file = TFile::Open(filename, "RECREATE");
TTree t("t", ""); // Register itself for shared ownership in TFile.
delete file;

the TFile needs to know that it can not delete the TTree as it usually does.

The IsOnHeap behavior is already disable on some platform where the UB actually implemented by the compiler/OS actively prevent the IsOnHeap detection.

We are moving away from this in the context of the ROOT v7 interface which does not rely on any implicit shared ownership. To avoid disruption on existing code, we are not planning on removing the feature in the old interface but recommend that one migrate to the new interface on their own schedule (once they are available).

In the meantime, there is already very few reasons to write new code that derives from TObject (counter examples includes of course code that needs to fit in an existing framework that leverage TObject or the ROOT collections)

1 Like

I fully understand the problems of having to maintain backward compatible code! That’s why I asked about phasing out and not about deprecating or even removing things.

Wow! So that means, that there are platforms where it would not make a difference, if our code would use = default? Very interesting!

That’s exactly what I was asking for: A plan to move away from this! Very good.