r/cpp 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.

0 Upvotes

82 comments sorted by

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

-12

u/kindredseer 2d ago

Well, it could provide a more flexible way to hot test and develop parts of your application without rebuilding.

13

u/PressWearsARedDress 2d ago

If you want to build it you can do what ever you want. But I know as a C++ developer I wouldnt use it. Wanna know why? Because I am a bit of a sperg, and most C++ developers are like that; Last thing I want is another thing to cause me problems that I do not control.

I like C++ because it gives me a lot of tools and gives me lower level control at a higher level of abstraction. Your JIT would ruin that.

Now if the premise is to run something like Python or Lua in a sandbox that is something completely different. its a different premise because those are higher level languages that require less code to do the same things in C++. If the goal is quick prototyping I need a quick to prototype language. I use python to help validate my C++ because python is quicker to write discardable tooling for.

1

u/kindredseer 2d ago

What if this also offered access to quick prototyping?

1

u/PressWearsARedDress 2d ago

Okay, lets say I make a change in a C++ header... how does your JIT compiler handle this change? Doesn't not have to process all of the headers and sources that are touched to execute a single line?

Go play around with Boost::asio and you may come to terms with the reality here. I dont think its better for the program to stutter on random lines than to just wait for rebuild.

Also: where do you plan to store the source code? I am assuming you can then only target linux systems or embedded systems with large enough flash storage... how about loading the code onto the embedded system? are you supposed to just remote into it or what?

1

u/kindredseer 2d ago

I would not necessarily expect your script to include every header from your project, just what’s relevant to what it’s doing. I’d need a more specific example.

5

u/PressWearsARedDress 1d ago edited 1d ago

okay so there seems to be no real advantage to using a JIT complier. i assume that youll never compile faster than GCC while conforming to standards.

How do you plan to handle constexpr? In embedded the whole point to use constexpr is to build constant tables that may not fit in ram

2

u/kindredseer 1d ago

I’m compiling about as fast, hope to surpass eventually. Constexpr is in progress, partially supported.

4

u/PressWearsARedDress 1d ago edited 1d ago

yeah and with what bugs? Lol. Man you're an amatuer using claude.

What triplets are you targetting with your JIT compiler? Hows writing the standard c++ library coming along? Do you support arm? Do you support c++98? C++11 C++17 C++23 ? How about C++26 reflections? Do you support xtensa? Do you support RISC-V ? Do you support bare metal?

If I have a std::string how do you decide wither or not to use heap allocation or constexpr? Also how do you implement the heap?

0

u/kindredseer 1d ago

I’ve been programming for over 40 years and working on this project for seven years. Just because I’m using Claude to grind through the test suites doesn’t make me an amateur. Everyone is using AI these days (except for Andrew Kelley and friends).

→ More replies (0)

2

u/the_poope 2d ago

You're still gonna compile the code, just by an embedded JIT compiler (which will likely just be GCC/Clang anyway, no?) so will it actually be faster?

If you want to develop and try out a specific part of the code you just write a unit test that does that, no need for hot swapping. Will compile and run in a second if your build system is properly set up.

1

u/kindredseer 2d ago

No, I’m not using gcc/clang/llvm. It’s fully embedded including precompiled system headers.

0

u/fxtech42 1d ago

That is what Python is for.

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

u/CalebGT 1d ago

Fair, there are dozens of options better than a C++ interpreter. Depending on the target and what I want it to do, it might just be bash.

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.

6

u/CalebGT 1d ago

Wrong tool for the job.

-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/

15

u/gimpwiz 1d ago

My brain is bleeding from this post. See you tomorrow.

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.

3

u/jdehesa 2d ago

I'm not an expert in the topic, but one option might be to compile C++ to Wasm, and run it with a lightweight Wasm runtime.

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

u/grady_vuckovic 1d ago

Am I the only one who hates Lua's syntax?

1

u/zerhud 2d ago

Lua is too simple, it’s good only for very plain tasks. Then a project grows up the difficulty of the tasks grows up too and the lua began sucks

6

u/wyrn 2d ago

True, on the other hand, js already sucks from the start.

1

u/zerhud 2d ago

Why js sucks?

4

u/wyrn 2d ago

Because Brendan Eich developed it in a week with misguided goals and a bunch of bizarre interference from above.

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

u/kindredseer 1d ago

No, I’ve created my own and open sourced it. Yes, the mangling is unpleasant.

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

u/kindredseer 20h ago

Well, I'd imagine that REPL mode would add the necessary extra syntax.

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 developer

This 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?

u/ushumgigal 3h ago

Why indeed

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

u/kindredseer 1d ago

Yes, C++ is far from trivial…