Understanding .undo and Interpreter::unload

Hi,

I’m having some trouble understanding what kind of transaction can be undone and which one will give me errors. I’m currently embedding cling in a C++ application and have tried both cling::Interpreter and cling::MetaProcessor approach. As I’m failing to understand what works and what doesn’t I’ve moved back to using cling straight from terminal so I can isolate a bit more the issues I’m facing.

Here’s what I’ve found so far: Simple declarations can be unloaded with the .undo command (and with mMetaProcessor->process( ‘.undo’, result, 0 ) or mInterpreter->unload( 1 ) ) :

int a = 1;
.undo
float a = 1.0f;

or

class Test {};
.undo
class Test {};

The following example seems to be quite similar to the first one (except for the #include) but will fail on the last input with the following error:

#include <vector>
std::vector<int> v;
.undo
std::vector<int> v;
In file included from input_line_3:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:362:5: error: constructor for
      'std::__1::__vector_base<int, std::__1::allocator<int> >' must explicitly initialize the base class '__vector_base_common<true>' which does not have
      a default constructor
    __vector_base()
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:503:5: note: in instantiation of member
      function 'std::__1::__vector_base<int, std::__1::allocator<int> >::__vector_base' requested here
    vector()
    ^
input_line_6:2:19: note: in instantiation of member function 'std::__1::vector<int, std::__1::allocator<int> >::vector' requested here
 std::vector<int> v;
                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:322:48: note: 
      'std::__1::__vector_base_common<true>' declared here
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __vector_base_common<true>)
                                               ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__config:623:54: note: expanded from macro
      '_LIBCPP_EXTERN_TEMPLATE'
#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;

Something like the following would also fail with the same kind of errors:

#include <iostream>
.rawInput 1
void test() { std::cout << "Hello!" << std::endl; }
.undo
void test() { std::cout << "Hello!" << std::endl; }

Am I missing something obvious or is it just a limitation of unloading code in Cling?

Thanks a lot for any suggestion.
Best,
Simon.

See sft.its.cern.ch/jira/browse/ROOT-7939

Hey, thanks for pointing this ticket out. I’m not sure if I’m having exactly the same issue as he’s talking about re-declaration with assignment. And there’s no mention of the weird errors I get.

Could it be a root version issue ? I just tried on Mac with the root trunk and it seems fine:

$ root
   ----------------------------------------------------------------
  | Welcome to ROOT 6.07/03                    http://root.cern.ch |
  |                                   (c) 1995-2016, The ROOT Team |
  | Built for macosx64                                             |
  | From heads/master@v6-07-02-323-g7f4b687, Feb 11 2016, 15:50:59 |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q'     |
   ----------------------------------------------------------------

root [0] #include <vector>
root [1] std::vector<int> v;
root [2] .undo
root [3] std::vector<int> v;
root [4] 

just tested on gentoo linux (x86_64) with root 6.06

root [0] #include
root [1] std::vector v;
root [2] .undo 1
root [3] std::vector v;
root [4]
no issues on my end

Thanks for testing this out! I guess you’re right, I’m not using ROOT but Cling (last git version) instead. So that’s probably it. Is Cling updated less frequently than root?

I generally stick with stable root because It’s easier to to grab the libroot, libcling .SO files straight from there. the same can’t be said about Cling directly… So If I were you. just sacrifice the extra hour compiling ROOT

No, every change of cling is replicated both in cling and ROOT’s repos.
–Vassil

I agree it would be nice to have libCling.so as a build option of cling standalone. Could you open a ticket for that?
–Vassil

Thanks Vassil.
So after seeing your messages I decided to grab a fresh version of cling by using this:

#clone llvm and apply patches
git clone http://root.cern.ch/git/llvm.git llvm_rep
cd llvm_rep
git checkout cling-patches

#clone cling and clang
cd tools
git clone http://root.cern.ch/git/cling.git
git clone http://root.cern.ch/git/clang.git
cd clang
git checkout cling-patches

And rebuilt the whole thing with:

#build release libraries
cd ../..
mkdir build
cd build
cmake -DCMAKE_INSTALL_PREFIX=../../lib/ -DLLVM_TARGETS_TO_BUILD="CppBackend;X86" -DCMAKE_BUILD_TYPE=Release ..
make -j8
make install -j8

Could it be that I’m missing something out in my build settings? I’ve checked both the docs on this website and the readme on github. I noticed that on github there’s an extra cmake llvm target called “CBackend”(https://github.com/root-mirror/cling#building), but it’s not present in the target folder, so if you try to build with this extra settings it will obviously fail. (There’s an issue on github mentioning this problem: https://github.com/root-mirror/cling/issues/4).

Anyway, with this fresh built, I re-tried the code I posted above, and unfortunately the same happen:

MacbookPro:bin simongeilfus$ ./cling

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ #include <vector>
[cling]$ std::vector<int> test;
[cling]$ .undo
[cling]$ std::vector<int> test;
In file included from input_line_3:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:362:5: error: constructor for
      'std::__1::__vector_base<int, std::__1::allocator<int> >' must explicitly initialize the base class '__vector_base_common<true>' which does not
      have a default constructor
    __vector_base()
    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:503:5: note: in instantiation of member
      function 'std::__1::__vector_base<int, std::__1::allocator<int> >::__vector_base' requested here
    vector()
    ^
input_line_5:2:19: note: in instantiation of member function 'std::__1::vector<int, std::__1::allocator<int> >::vector' requested here
 std::vector<int> test;
                  ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:322:48: note: 
      'std::__1::__vector_base_common<true>' declared here
_LIBCPP_EXTERN_TEMPLATE(class _LIBCPP_TYPE_VIS __vector_base_common<true>)
                                               ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/__config:623:54: note: expanded from macro
      '_LIBCPP_EXTERN_TEMPLATE'
#define _LIBCPP_EXTERN_TEMPLATE(...) extern template __VA_ARGS__;

Could someone confirm me that I’m not building the libraries properly?
Thanks a lot!

1 Like

It seems to me that the .undo doesn’t work on MacOS. MacOS uses libcxx instead of libstdc++. It looks like a bug in the unloading on MacOS.
–Vassil

i can confirm this error, any update about that?

No update yet - we simply don’t make enough progress with unloading. I will see whether I can devote some weeks to this during summer!