1

So I coming from a python world, trying to learn cpp fast. (at least the basics). The thing that I miss most from the python world was - how you can just add breakpoint anywhere in the code and start an interactive repl session with the context.

I am looking for something similar in cpp. I know this not going to be popular in cppworld, but it really helps in prototyping a solution fast! I found https://github.com/tehrengruber/Defrustrator which gives me some more promise.

There is also this: https://github.com/inspector-repl/inspector which looks interesting and is similar to what I am looking for!

Would it help if I embed the cling interpreter inside my program?

Thanks for reading!

EDIT: To clarify, ideally I am seeking something on lines of - how you can enter swift repl while using lldb. I am not sure why CPP community does not see advantage in this. This would be an amazing feature to have! This would encourage a lot of people like myself to take up CPP more readily.

spunkpike
  • 94
  • 2
  • 13

1 Answers1

3

This is not directly answering your question, but if you run your program under lldb and stop somewhere, the lldb expr command is pretty close to a REPL. It doesn't run in a REPL like mode where you are just entering program text, instead you run the "expr" command and either put in the program text as command arguments or hit a return to enter into a little mini-editor. But you can call any methods of any of the objects you have, and can make new objects and in even make new classes and play with them as well as program objects.

There are some provisos. You can create classes in the expr, but you have to do it in one go (C++ is not about incremental building up of classes). Because the expression evaluator is meant primarily for exploring extant code and tries to avoid shadowing program variables, all types & variables defined in the expr command have to be preceded by a $. So for instance:

(lldb) expr
Enter expressions, then terminate with an empty line to evaluate:
  1: class $MyClass {  
  2: public:  
  3: int doSomething() {  
  4:   return m_ivar1 * m_ivar2;  
  5: } 
  6: private: 
  7:   int m_ivar1 = 100;  
  8:   int m_ivar2 = 200; 
  9: }
(lldb) expr $MyClass $my_var 
(lldb) expr $my_var.doSomething()
(int) $0 = 20000

So you can do a fair amount of playing here.

The other funny limitation is that though you can define classes in expr, you can't define free functions. By default the expr command is trying to run expression text "as if it was typed at the point you are stopped in your program", so you will have access to the current frame's ivars, etc. But under the covers that means wrapping the expression in some function, and C/C++ doesn't allow internal functions...

So to define free functions and otherwise more freely add to the state of your program, you can use the --top-level flag to expr to have your expression text evaluated as if it were in a top-level source file. You won't have access to any local state, but you aren't required to use initial $'s and can do some more things that aren't allowed in a function by C.

Wang Liang
  • 4,244
  • 6
  • 22
  • 45
Jim Ingham
  • 25,260
  • 2
  • 55
  • 63
  • Thanks! That was very helpful! I did not know I could create a class within `lldb`. Is there a tutorial for all of this? I didn't find a lot of info on the documentation. – spunkpike Jun 04 '22 at 18:28
  • Is it also possible to create functions inside `lldb`? – spunkpike Jun 06 '22 at 14:56
  • 1
    Creating functions was what I was talking about in the comment regarding `--top-level` above. You can create free functions (as opposed to methods) but you have to use `--top-level`. Again, this isn't a "real" "REPL" environment, which should allow you to build classes incrementally, swap out methods, etc. The swift REPL does allow these things. There's a fair bit of help on the `expression` command that drives all this in the on-line lldb help. But making a "real" REPL for C++ isn't something we are currently working on, there isn't a tutorial dedicated to that feature. – Jim Ingham Jun 06 '22 at 17:02
  • Understood. Thanks for answering that! One more thing: I was going through the lldb documentation. And found this - https://lldb.llvm.org/man/lldb.html#repl. I did some more digging and found this: https://reviews.llvm.org/D87281 Does it mean that a C repl is supported? If yes, can you please provide me more links to learn about it? Or is it the same thing you mention? – spunkpike Jun 07 '22 at 21:08
  • Also, thanks for answering the question! Can you please suggest me some links where I can see some examples / tutorial for lldb with `$` and `--top-level`? I just want a demo/guide which has enough examples to demonstrate `lldb` capabilities as a repl – spunkpike Jun 07 '22 at 21:26
  • ^ Like I did not know that one could create classes with `expr`. That is so awwwsome! I just want to see what all is possible. I watched a lot of videos on YouTube about it; None seemed to cover that this was possible. Thanks again! – spunkpike Jun 07 '22 at 21:28
  • Note first, the "expr" command in lldb was part of the original lldb, long before the REPL was added as part of the Swift project. The first goal was just to allow users to play with code "in the context of the frame you are stopped in". So it wasn't aimed at REPL-like functionality. But it was really useful to be able to inject user-defined types and variables, so those were added. The idea of using it for a REPL was a part of the Swift project. TTTT the C REPL was mostly added so that the base classes for the Swift REPL were testable on the non-swift lldb sources. – Jim Ingham Jun 08 '22 at 15:43
  • 1
    There were a couple of talks in past LLVM conferences about turning this into a more full-featured REPL, but that's still waiting for volunteers to really push that project forward. – Jim Ingham Jun 08 '22 at 15:44
  • Hi again! I was just wondering if `lldb` works as efficiently on Ubuntu (linux) as it does on OSX. I just tried issuing `(lldb) expr --top-level` and I got a response `error: :1:3: use of undeclared identifier 'top'` Any ideas? – spunkpike Jun 17 '22 at 03:31
  • 1
    Try `expr --top-level --` - you need to tell lldb that you are done passing options to `expr`, and starting to pass the expression. – Jim Ingham Jun 18 '22 at 07:14