Issue with ClassImp when compiling with Clang 5.0

I have updated my compiler to LLVM/Clang 5.0 and I am now having an issue compiling a ROOT dictionary using ClassImp. I am passing -Werror,-Wzero-as-null-pointer-constant to the compiler as I have done it with previous versions, where it worked flawlessly.

However, now I get:

../src/objects/Object.cpp:20:1: error: zero as null pointer constant [-Werror,-Wzero-as-null-pointer-constant]
ClassImp(Object)
^
/cvmfs/clicdp.cern.ch/software/ROOT/6.10.08/x86_64-slc6-llvm5-opt/include/Rtypes.h:336:24: note: expanded from macro 'ClassImp'
#define ClassImp(name) ClassImpUnique(name,default)
                       ^
/cvmfs/clicdp.cern.ch/software/ROOT/6.10.08/x86_64-slc6-llvm5-opt/include/Rtypes.h:332:41: note: expanded from macro 'ClassImpUnique'
            GenerateInitInstance((name*)0x0)->SetImplFile(__FILE__, __LINE__); \
                                        ^
1 error generated.

and I don’t really understand why this problem appeared only now. Please observe that I include the ROOT_INCLUDE_DIRS via CMake using the SYSTEM tag, so I’m not sure why the compiler complains here. Maybe because all ClassImpl are preprocessor defines and are placed in my source code directly?

Do you have any idea how to solve this issue?

Can you try to replace 0x0 with nullptr? Or just disable the warnings.

In CMake, you can add SYSTEM to the include directories, i.e.

find_package(ROOT REQUIRED COMPONENTS TMVA TreePlayer) # add whatever you need
include_directories(SYSTEM ${ROOT_INCLUDE_DIR}) # add SYSTEM here

Hi @behrenhoff,

as stated just two lines above your answer, I am including them as SYSTEM headers.

Replacing 0x0 with nullptr is not possible and certainly not a solution, since I am using a centrally installed version of ROOT and the compilation error appears on CI machines of CERN’s GitLab.

Also, disabling the warning doesn’t seem like a solution to me - we added it for a reason.

What I would like to understand is why this has not appeared with earlier versions.

Which compiler version were you using when it worked?

Look at Compiler Explorer and play with the compiler versions: clang didn’t support that warning in versions prior to 5.0, clang 4.0.1 says
error: unknown warning option '-Wzero-as-null-pointer-constant'; did you mean '-Wint-to-void-pointer-cast'? [-Werror,-Wunknown-warning-option] Compiler exited with result code 1

You want errors when casting 0 to T*, you get an error when doing that. So not doing the cast is the only real solution in my opinion.

Another solution: you could probably remove the call to ClassImp. As far as I know, it is no longer necessary.

As for your question why it was working previously: no idea, sorry :frowning:

And by the way: locally I am already working with a TMVA version in which all 0’s and NULL’s have been replaced with nullptr. Maybe I should create a pull request for that :slight_smile:

1 Like

Hm, that would explain at least why it didn’t appear before - the previous version I used was Clang 4.0.0.

I agree that really replacing the 0x0 with nullptr should be the solution, but it should probably be done upstream instead of me editing the ROOT sources locally… :slight_smile:

Do you have a pointer for me concerning the removal ClassImpl? Removing it would be the easiest solution for now - but I don’t want to create compatibility issues with users…

Thanks for your help!

SO might not be the best resource for ROOT related questions but I am almost sure I have read this somewhere in the ROOT documentation (can’t find it at the moment).

Uh, great, completely removing it indeed seems to do the job - and all unit tests are still running.

Thanks a lot!

ClassImp is needed if and only if you want/need to record the source file name into the TClass object (i.e. you probably don’t need it unless you are still using THtml).

Okay, thanks for the info - we are indeed not using THtml but regular Doxygen.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.