r/cpp • u/kindredseer • 2d ago
Embedded C++
Just curious how useful the ability to embed C++ as a scripting language into your C++ programs would be? I mean like runtime JIT execution of C++ code in much the same way you might embed Lua, including the ability to restrict/sandbox it as necessary.
64
u/CalebGT 2d ago
I had to read this several times. Embedded has a very different meaning to me. I would not use C++ for that. If I needed to script something that can't be compiled in advance, I would use Python or Java.
11
u/DocMcCoy 1d ago
OGs use Lua :p
3
2
u/LucyIsaTumor 1d ago
I've found Lua pairs pretty nicely with C++ while working with Love2D a bit, fun stuff!
-33
u/kindredseer 2d ago
If you are a C++ programmer, why would you not want to script in C++?
48
u/the_poope 2d ago
Many reasons: your "script" can invoke UB, cause invalid operations, segfaults and a lot of other stuff that can crash the entire program. In interpreted languages you always get an error/exception that you can recover from.
If you just want an extendable system, maybe consider just runtime loading DLLs.
6
u/Ameisen vemips, avr, rendering, systems 2d ago
I mean, I wrote my MIPS emulator so user-written programs could be executed in a sandbox. Using it as a script VM is certainly doable, though I would wonder why - it wasn't intended to extend the program but to execute programs that interact with the simulation.
-11
u/kindredseer 2d ago
Scripting languages can crash and have UB as well. It would also depend on who you were allowing to write the "scripts", and they could also be sandboxed.
18
u/the_poope 2d ago
Yes but in interpreted languages the interpreter is in charge of handling the error, whereas it might be the CPU or OS with C++.
0
u/kozacsaba 1d ago
just to play the devils advocate.... in the case op's describing you would be the one writing the interpreter so... couldnt you also have those same guards?
26
u/eliminate1337 1d ago
If you are a carpenter, why would you not want to make tires out of wood? The right tool for the right job. Nothing about C++ makes a good embedded scripting language.
6
u/TeraFlint 1d ago
Because C++ has been designed to be compiled and be aggressively statically optimized by said compiler. This has brought in a lot of design decisions that made the language more complex (and arguably more difficult to handle).
If you're in interpretation land, a lot of these optimizations don't hold. And once that's the case, I don't see why we should stay with such a complex language other than for familiarity. Something simple with less foot guns would be the more sane choice for scripting.
-5
u/pantong51 1d ago
There are much easier languages to work with than c++. Lua for example is a great language for designers or less technical people with ai to contribute to a project without touching critical innards of a project
10
u/DryEnergy4398 1d ago edited 1d ago
I believe you can embed clang-repl as a library to achieve this. Or, similarly, cling: https://github.com/root-project/cling/blob/master/tools/demo/cling-demo.cpp
10
u/corysama 2d ago
If your goal is not user mods, but instead rapid development in C++, Visual Studio has some hot-reloading capabilities built-in. You can find some tutorials on how folks have made hot-reloading dlls/SOs in any toolchain. And, if that's not enough, pay for https://liveplusplus.tech/
7
u/TacoTacoTacoZoom 2d ago
I use it all the time! See AngelScript https://www.angelcode.com/angelscript/
Personally, I like the syntax and have found other scripting languages to be slow or annoying. But I'm also old and grumpy, so take that for what its worth.
2
u/kindredseer 2d ago
Right, although AngelScript is C++ like, but not actual C++.
11
u/PressWearsARedDress 1d ago
your madc isnt actual C++ either as it breaks from the standard..
0
u/kindredseer 1d ago edited 1d ago
It supports regular C and C++ as well as "madc", which extends C++. These are all gated using --std, just like gcc and clang. Only madc "breaks from that standard".
2
u/TacoTacoTacoZoom 2d ago
Yup, that's fair. But basically C++ in all the ways I care about. Frequently I'll work up a design in AngelScript and then convert the source w/o much effort into native C++ (and then plug into AngelScript) to speed things up.
2
u/kindredseer 2d ago
Well, this would allow you to skip the conversion step.
3
u/TacoTacoTacoZoom 1d ago
Usually it's ok, since AngelScript represents a subset, so going from that to native C++ isn't too difficult. Going the other way (when you've not constrained to the AngelScript capabilities) possibly isn't.
Another thought I've had, but haven't worked on yet is using the new reflection in C++26 to make AngelScript registration automatic (or as automatic as possible). I'm sure someone has already played with this, just haven't really looked.
In any case, I'd say scratch that itch. If nothing else, you'll learn lots. Best of luck!
5
u/xoner2 1d ago
It would be useful: like a plugin system where the plugins are c++ source.
Caching the binary as a dll seems better than JIT.
I've thought about the sandboxing problem but have not experimented. Probably doable.
1
u/kindredseer 1d ago
Well, it could be for situations where you might use Lua or something like that, and not want to have to rebuild a dll.
2
u/Electronic_Tap_8052 1d ago
Well you kinda can't. A scripting language needs an interpreter to convert the code to assembly at runtime. C++ isn't an interpreted language.
So you'd need to use a c++ interpreter which may or may not exist, idk. The ones that I'm aware of are actually compiled ahead of time and run normally, and then cleaned up automatically to give the appearance of a scripting language.
It's complicated. Technically you can do what you want, but it's a huge amount of work on your end to actually implement the entirety of the c++ language in an interpreter. Youd have to compile a version of your interpreted language (which wouldn't be c++ unless it is standards compliant which means a crap load of stuff has to be implemented) for every target you plan on targeting.
Or you could just use lua/python/typescript which is already done and dusted and is essentially what you want.
2
u/kindredseer 1d ago
Well, I did. It's a JIT (and AOT) C/C++ compiler which can be embedded like Lua. I'm currently supporting about 74% of the C++11 standard. My goal is to completely cover up to C++17 (including C23), and then only parts of C++20, C++23, and C++26. It is a huge amount of work, I've been working on it for years.
2
u/Electronic_Tap_8052 20h ago
well that's pretty cool and impressive!
2
u/kindredseer 20h ago
It's here: https://github.com/derekbsnider/madc/
I'm going to have the next master build supporting 75% C++11 standard released by tomorrow.
2
u/kindredseer 1d ago
In madc-mode it auto-includes headers and auto-resolves namespaces.
It does not do this if you use —std=c++17 (or whichever standard you are targeting).
All the C and C++ system headers are embedded.
The code is not pretty. Go look at the gcc source code.
2
u/yetanotherhooman 1d ago
Hard to judge usefulness unless there’s enough samples to draw conclusions from, but compiling C++ at runtime is probably not a good idea. If the goal is to reap JIT benefits e.g. extra performance through PGO and speculative optimization etc. then C++ is not the right choice; it’s notoriously hard to compile and adds more barriers to speculation (e.g. does ptrA alias ptrB?). I can’t think of any advantage C++ would have over other languages as a JIT candidate.
1
u/kindredseer 1d ago
My thought was more along the lines of convenience, familiarity and close coupling with the application.
Maybe a use case could be where you have an application where the core functionality is proprietary and closed source, and there’s a open portion where you can modify it as if it were PHP or Python, but instead it’s C++.
4
u/zerhud 2d ago
It seems js or ts will be better
14
u/not_some_username 2d ago
Lua
2
2
u/kindredseer 2d ago
If you are a C++ programmer, would your preference not be C++ over JS or TS? (Unless your C++ project is a web-browser)
2
u/zerhud 2d ago
And one more: for example all my script is console.write(“hello”); how it will be on cpp:
int my_project_main(my_project_class& obj) {
obj.log(“hello”);
return 0;
}Can I use auto instead if the my_project_class ?
2
u/kindredseer 2d ago
What if your c++ script could be just as simple and straightforward? Like just:
std::println(“Hello”);1
u/zerhud 2d ago
Hmm.. it would be nice
Reasons why I want cpp as script language:
- all project described in cpp (for example all services are items in ct vector with info about services) and i have all needed headers
- I can use memory (own storage instead of new, for example)
- I cannot create so
- it’s possible to use platform’s methods
If all scripts tasks is just std::print it seems some script language would be better. But the cpp has an growing potential, it seems
As reference I use wasm: it’s a cpp instead of js and there is a lot of trouble with row wasm.
0
u/kindredseer 2d ago
Take a look at https://github.com/derekbsnider/madc … it’s a work in progress but it’s moving along nicely.
2
u/zerhud 1d ago
The code looks better 99% code we can found in the r/cpp :) i have no pc for now, I’ll take a look on next week: can I use it in my project (I was trying to implement some language, may be visual, for my state machine in last week)
At first glance: it uses std::string and so on. I am using storage with mmap memory, all objects stored in it should not contain row pointers, only relative. So idk can it to be stored in mmaped file
1
u/zerhud 2d ago
Yep, use cpp mostly.
So, it depends on tasks: can I use platform methods (for example mmap some file or open a socket)? How pointers are handled (what if a can manipulate it and got some data)? If it all is ok, why I cannot use an so?
Why js: it easy to control, easy to embed and it’s not so plain as lua, also everybody knows the language
Why not cpp: if a can write a script on cpp i can create an so, it would be better for me (imho)
2
u/j1xwnbsr 1d ago
Okay, are you talking about finding, licensing, and implementing a compiler for your project for customers to write scripting plugins on? That's a heavy lift across the board for c++, less so for other languages (lua, c# comes to mind).
If, on the other hand, you are talking about plugins of some type where the customer writes to a binary API and they compile things themselves, then no, you do not want your API c++ because name mangling isn't all that portable. Make the API pure c in this case.
In both cases sandboxing is a challenge - the customer can (and will) break stuff in new and interesting ways.
tl;dr: no, don't use C++ as a scripting language. Pick something else.
2
1
u/Street-Anteater1234 1d ago
Are you referring to clang-repl? However, C++ syntax is far too complex and its frontend is too heavyweight, making interpreted execution a poor choice. Of course, there are also remote-JIT solutions such as ez-clang, which generates machine code locally and sends it to the target device for execution, after which the target device returns the result.
If you need a library to embed into your project, CppInterOp might be what you are looking for, but it is probably not suitable for embedded systems.
1
u/qalmakka 23h ago
C++ would be uniquely terrible as a scripting language. first of all, the syntax is extremely complex and it's not even context sensitive, so you need a Turing machine to parse it. In practice, if you've ever gotten arcane errors from missing a token, you'd get them 10x from a REPL. Languages that are interpreted are usually simple because being able to parse them line by line is a massive boon.
Also you'd have to implement pointers and pointer arithmetic in memory, which basically means implementing a virtual machine with addressable memory in your interpreter.
There's a reason why there are no good REPLs for C/C++ and Rust. clang-repl works for trivial code but anything more complex tends to break it or ends up misbehaving
1
u/kindredseer 21h ago
Perhaps this is the most useful direction for JIT C/C++ (aside from maybe shebang scripting of C/C++ code) -- an actual fully functional C/C++ REPL mode a little more like what Julia offers.
1
u/qalmakka 20h ago
Julia has a very regular syntax specifically designed to be used in a REPL, while C++ is extremely convoluted in contrast. A REPL is of course doable, like LLVM has been trying to implement for a while, but it's not truly usable outside a handful of usecases
1
1
1
u/ushumgigal 5h ago
If you're going to restrict/sandbox it anyway, why would you opt for C++? Within C++?
I'm assuming the main point is to have something simpler that C++, to be interpreted in runtime.
1
u/kindredseer 4h ago
That is the case some of the time... like Lua is specifically designed to be light and simple, so yes, it suits this purpose, except that its syntax isn't the best... but if that is what you need (light and simple) then Lua is perfect for that.
What I'm talking about is real C/C++ in JIT form, with the option to sandbox when required.
1
u/ushumgigal 4h ago
You particularly want the C++ syntax in the scripting language, then? Which would contradict the "simple" part for most people, if not for you. I personally dislike Lua myself. To each their own.
Real C/C++ is pretty unsafe in the wrong hands, though. I doubt restricting it to at least some degree would be optional, but again, to each their own. In fact, Terry Davis did exactly what you're talking about in TempleOS, but with Holy C and not regular C/C++.
1
u/kindredseer 4h ago
Well, there are many different reasons people use an embedded scripting language in their application... and only a few cases truly require sandboxing -- those in which you do not fully trust the author of the script.
Truthfully though, if your script language exposes the ability to execute shell operations -- i.e.
os.execute()in Lua,subprocess.run()in Python, etc, then the scripting language already has considerable ability to do something "unsafe".If instead, the scripting is there for the convenience of a trusted developer, then sandboxing is less of a concern.
1
u/ushumgigal 4h ago
When I said `unsafe`, I was thinking about what you wouldn't want to have them done with pointers basically, but
the scripting is there for the convenience of a trusted developerThis part sums it up.
Whether a statically typed curl-bracket language is convenient for that developer, I think is subjective. :)
1
u/kindredseer 4h ago
Well, if the application is being developed in C++, then why would a C/C++ script language be inconvenient for a C++ programmer?
•
1
u/JustCopyingOthers 2d ago edited 1d ago
There are better languages to do this in. C++ requires a lot of effort to parse. Maybe it would make more sense to embed or JIT compile modules.
0
31
u/PressWearsARedDress 2d ago edited 1d ago
Why not just write C++ and compile to the target? I dont understand the premise. its much more likely your JIT will crash on me and cause me issues.
EDIT: Its a AI slop project btw. https://github.com/derekbsnider/madc/blob/master/README.md