I’m trying to compile a code depending on ROOT with gcc-12 on Ubuntu 22.04.1. The ROOT distribution I used was the pre-built binary compiled by gcc-11 for Ubuntu 22.
In the ROOT header ROOT/RangeCast.hxx, at line 188 and line 227, gcc-12 reported that the reference to std::span is ambiguous. The ambiguousness is raised from std::span (in gcc-12 standard header span) and std::__ROOT::span (at ROOT/span.hxx:155).
Here is the typical output:
In file included from ${ROOT_DIR}/include/TGeoManager.h:20:
In file included from ${ROOT_DIR}/include/TObjArray.h:25:
In file included from ${ROOT_DIR}/include/TSeqCollection.h:25:
In file included from ${ROOT_DIR}/include/TCollection.h:33:
${ROOT_DIR}/include/ROOT/RRangeCast.hxx:188:16: error: reference to 'span' is ambiguous
return std::span<U>(arr, arr + N);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/span:104:11: note: candidate found by name lookup is 'std::span'
class span
^
${ROOT_DIR}/include/ROOT/span.hxx:155:7: note: candidate found by name lookup is 'std::__ROOT::span'
class span {
^
In file included from ${ROOT_DIR}/include/TChain.h:24:
In file included from ${ROOT_DIR}/include/TTree.h:36:
In file included from ${ROOT_DIR}/include/TClass.h:29:
In file included from ${ROOT_DIR}/include/TObjArray.h:25:
In file included from ${ROOT_DIR}/include/TSeqCollection.h:25:
In file included from ${ROOT_DIR}/include/TCollection.h:33:
${ROOT_DIR}/include/ROOT/RRangeCast.hxx:186:27: error: reference to 'span' is ambiguous
RRangeCast<T, false, std::span<U>> RangeStaticCast(U (&arr)[N])
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/span:104:11: note: candidate found by name lookup is 'std::span'
class span
^
${ROOT_DIR}/include/ROOT/span.hxx:155:7: note: candidate found by name lookup is 'std::__ROOT::span'
class span {
^
Compiling on gcc-11 is all right. I wonder why this error occurred in gcc-12 but not in earlier versions, since there is std::span after gcc-10. Perhaps those standard headers have not included span before. Anyway, I report it here.
I understand what you mean, but I was complied my code with -std=c++20 on both gcc12 and gcc11 (actually -std=gnu++20, generated by cmake CMAK_CXX_STANDARD=20), and gcc11 works while gcc12 don’t. I’ve not checked the root-config, but I guess the pre-built root is built with gcc11 default, c++17.
note that ROOT does not have good C++20 support. Cling might have issues. The next release should improve the situation.
About your problem. I just tried to compile ROOT from source with -DCMAKE_CXX_STANDARD=20 (gcc 12 still defaults to C++17) and encountered a few issues.
@ZhaoSH what does root-config --cflags print for you? If among the flags there is -std=c++20, with what cmake flags did you compile ROOT exactly? (If among the flags there is -std=c++17 instead, that’s the issue – mixing C++ standards is not supported).
Well, I did mix the standards. But it‘s interesting that if gcc-11 is used instead of 12, this error will not occur even if the standards are mixed. Anyway, I’ll compile a ROOT with C++20 and try again. I will reply if there are any issues.
As I mentioned above I just tried it out and at least with the default compilation options it does not work. With some luck it might work with -Druntime_cxxmodules=OFF since the errors I saw came from there (but there might be other problems hidden behind those – the latest version of the interpreter is not C++20-ready).
Thank you very much, and I’m also sure the issue is mixing the standards. I’m just compiling a ROOT-based project with C++20 instead of using cling to interpret these codes, so cling might not be an issue. For now, although I can use gcc-11 to compile my program with a standard mismatched ROOT, I will recompile the ROOT with C++20 for safety.