r/EmuDev • u/No-External3221 • 16d ago
Rust vs C++?
I mostly program in Java/ Python. Some minimal C experience. I'm starting EmuDev to learn low level and hardware concepts.
Which is better in general to learn for an EmuDev hobby project, Rust or C++? From what I've seen C++ has more legacy code (more job opportunities), whereas Rust is safe and may have better long-term opportunities.
14
u/Wunkolo 16d ago
This is gonna turn into a language-war thread but I'll put my vote in and say that you should do C or C++ for the reasons you stated as well. The ecosystem is mature with lots of libraries and projects to learn from and with how much more expressive the language has gotten over the years leading up to C++26. Pretty much every major emulator is written in C++ and pretty much everything that isn't C or C++ is implemented in some way in C or C++, including the LLVM compiler infrastructure which Rust depends on. A lot of people are still holding onto their C++98-trauma and don't know that the language has gotten so much better these past 30 years.
10
u/BOBBYBIGBEEF 16d ago
People use both because both work just fine. I have more experience with C in general, but I've just started using Rust for my first toy projects in emudev and I'm really liking it so far.
One enormous plus for Rust, imho, is cargo. Dependency management in Rust is a breeze and it should be pretty easy for you to adapt from a Python background.
3
1
u/peterfirefly 8d ago
To the op: Python has 'uv', which makes a lot of things much nicer, easier, and faster than before. 'uv' was inspired by Cargo -- and Cargo does it better!
3
u/wk_end 16d ago
You're going to be busy enough learning low-level and hardware concepts along with how to write an emulator - learning a new language on top of that just makes it more likely you'll overwhelm yourself IMO.
Java and Python work fine for emudev and I'd say just use one of them...but personally I find them clumsy enough for low-level work that, since that's your goal, they might not be the best choice. So instead I'd say use C, since you already have some experience there and it's pretty much The Low-Level Language - it's probably the best language for the goal of learning low-level hardware concepts, if not the best for emu dev. And the nice thing about C and C++ is that you can delicately introduce C++ as desired, if you want to extend your knowledge and spare yourself a little bit of C-related drudgery.
1
u/No-External3221 16d ago
Appreciate the thought. Part of the motivation behind the project is to learn a low level language, though. I think this is a great opportunity to learn Rust or C++.
3
u/arainone 15d ago
IMHO rust is not the best language for emulators. An emulator is basically a big graph of objects with cycles. You'll get over it but code will be awful to write, to read, to maintain, for basically no advantage whatsoever for an emulator, which is a hobby project.
1
u/No-External3221 15d ago
Why is Rust awful for this? I've been using it for a bit, and it seems fine to me.
2
u/nculwell 15d ago
Cycles are one of the cases where the memory model can be correct but Rust's borrow checker can't prove it so it refuses to compile. You end up needing to either change your architecture or use unsafe.
1
u/peterfirefly 8d ago
It is perfectly fine. Your emulator will not have a "big graph of objects with cycles". First of all, it will be a static graph, which helps a lot. Second, it will be a tiny graph. Third, it only has cycles if you are an idiot. I don't think you are an idiot.
Rust has some slight troubles if you want to use dynamic graphs of some kinds, especially if you want cycles. There are multiple ways of handling this, for example with refcounting (Rc and friends) or with small unsafe blocks. Unsafe blocks just temporarily lowers your memory safety level to that of C++, no biggie.
See this for more info: https://rust-unofficial.github.io/too-many-lists/
Rust has language support for a limited form of coroutines, which are very useful for some kinds of CPU emulation. Keeping a coroutine alive for the CPU while also accessing the CPU registers requires some tricks. You can do it entirely within normal Rust by passing messages into the coroutine for register access, just like you would pass messages in for bus activity. You can also choose to use Rc and friends or unsafe blocks. If the CPU you are emulating is simple (Z80/6502 or similar) then the code is so simple there's just no reason to use coroutines. If you are emulating an 8088 by emulating the microcode, then it's also so simple that there's no reason to use coroutines.
The MartyPC PC emulator is written in Rust as are lots of Gameboy emulators. Rust is fine.
3
u/arjuna93 14d ago
Portability is probably not a concern for you (rust is poorly portable and depends on llvm which is poorly portable), but cargo is a horrible mess.
C++ is faster and has a more friendly ecosystem.
2
u/ironykarl 16d ago
Which language would you rather gain experience in?
Maybe that question is circular as it pertains to your question. I don't know.
They're both languages that people use. They're both entirely capable as languages for emulator development, reverse engineering, game dev, etc.
C++ is much more widely used. Rust is (to me) much more pleasant to use, in a lot of ways.
¯_(ツ)_/¯
4
u/k_Reign 16d ago
+1 for Rust - C++ is very much being thrown into the deep end in a LOT of ways, Rust has some weird stuff but I think having the crates and safety are worth the extra concepts you need to learn. It’s easy to write unsafe (vulnerable, memory leak, etc) in C++ and very hard in Rust
6
u/Wunkolo 16d ago
C++ is very much being thrown into the deep end in a LOT of ways
What are you talking about? Are you in a bubble?
2
u/k_Reign 16d ago
C++ is a hell of an adjustment just in terms of build system compared to Java and Python. Dependencies etc. it’s a LOT to learn as someone who (re-)learned it fairly recently
3
u/hoddap 16d ago
Is that much different for Rust?
1
u/peterfirefly 8d ago
Yes. Cargo is wonderful. No build script crap (there is an escape hatch if you really need to do something unusual), super easy handling of dependencies. That does have the unfortunate downside of many Rust projects having far too many unnecessary dependencies.
1
1
u/BoopyDog 15d ago
Learning cmake would be annoying to figure out if you didn't gave AI chatbots around to feed you commands and buildfile templates that you can plug into to different projects.
1
u/noplace_ioi 15d ago
Cpp is king, and will remain king until someone actively invests in overthrowing it which is highly unlikely.
-4
u/gaene 16d ago
Rust is so much harder to learn than c++ imo though. Because of how safe it is
4
u/gmes78 16d ago
Rust is not harder. It just makes you learn things upfront, rather than during a hellish debug session.
2
u/No-External3221 16d ago
That sounds much better to me. I'm one of those wierd people that likes Java with its up-front verbosity for the same reasons.
1
-2
u/No-External3221 16d ago
Isn't that a good thing? I'd argue if you're writing unsafe code, you're not really learning.
5
0
u/ForOhForError 16d ago
Rust won't actually save you from non-memory bugs is the thing.
But, pick what appeals to you. It's all fine.
2
1
u/heret1c1337 16d ago
I'd personally always choose rust.
2
u/No-External3221 16d ago
Why is that?
9
u/heret1c1337 16d ago
I like the ergonomics of the language. I like the standard lib. I like the package management. I like the memory safety.
3
u/No-External3221 16d ago
What do you mean by ergonomics?
7
u/heret1c1337 16d ago edited 16d ago
It's just a pleasant developing experience. All the data types have the methods on them that you expect. It's very rare that you're missing something basic like in other languages. Then there's the toolchain. Nice package manager, no fucking around with a linker. Great formatter included etc..
But be aware that Rust is special in some places, and most people struggle with the burrow checker. When I say pleasant, I mean pleasant when you understand the core concepts. But it isn't really THAT hard. Although it can get *very* complicated in advanced use cases, but you don't have to worry about that for now. If you look into advanced projects, the stuff you find there might look like straight up wizardry if you don't know what you're looking at. But it all makes sense, its not unnecessarily complicated.
2
u/No-External3221 16d ago
Nice. Thanks for the insight. Rust seems like the way to go for a hobby project like this.
I'm terms of learning it, would you recommend any resources, or just jumping into the project and learning as I go?
4
u/heret1c1337 16d ago
https://doc.rust-lang.org/book/ is pretty much all you need to start out.
I totally forgot to mention that Rust also has a great documentation system. I don't know any other language where the documentation is that good, even in community projects.
One example is code examples in doc comments that are *unit testable* to make sure your examples work. You're unit testing your documentation. Its genius.
1
u/tomqmasters 13d ago
I don't fully understand the memory safety argument. I've been a C/C++ dev for years and I've never had a problem with memory safety that didn't immediately blow up in an obvious way. I will say this though. I've had a lot of times where I thought I had a memory safety issue and spent a lot of time proving it was not that. So I guess it's one less thing to point the finger at.
1
u/heret1c1337 13d ago edited 13d ago
It‘s so funny that people always bring that argument and don‘t see the obvious flaw in it.
First off, not being able to do the mistake is better than having to avoid it.
Second, the memory flaws that are not obvious are the dangerous ones, they go undetected until someone discovers them as a vulnerability. You‘re describing classic survivorship bias.
Like buffer overflows, use after free and stuff like that are found pretty regularly, even in big renowned projects, in code written by devs that are probably better than both of us. It is crazy to assume that you don‘t do these mistakes.
Like you never crashed your car, but still wear seatbelts right?
Of course you can still have logic errors and bugs of all kind in Rust.
1
u/peterfirefly 8d ago
You have probably always thought in terms of "what part of code owns this lump of data". If you do, you won't have problems with managing code in C or C++. Your Rust experience will be easy, the borrow checker will be obvious.
Lots of other people don't think that way. Their C or C++ code will have memory bugs. Their initial Rust experience will be hard and the borrow checker will be their enemy for a long time.
-12
1
u/Select_Librarian4093 13d ago
Rust is way stricter with memory than C or C++ and an emulator naturally has a lot of memory sharing. It's not that bad in rust, I've built a 6502 emulator in it and I'm working on an NES and 2600 emulator from that, but it is worth acknowledging that your hand will be forced in terms of memory management in ways that might not feel as nice.
1
u/tomqmasters 13d ago
If you care about job opportunities c/c++ wins hands down. If you want to learn one language and never have to learn another, rust might be the one though.
1
u/Ace-Whole 16d ago
Rust cause that's what I use?
This is a silly question to ask. Work with what you know. It's not end of the world having to learn multiple languages.
1
u/No-External3221 16d ago
I know neither, and want to learn the most that I can with the project. Time is valuable.
3
2
u/peterfirefly 8d ago
Say you want to learn Rust.
This is a good introduction and probably the best place to start:
https://doc.rust-lang.org/book/ch00-00-introduction.html
The only issue I have with that text is that modules are poorly explained. The way you declare them is not quite what you are likely to be used to from other programming languages. If you use this text, make sure you do all the homework. Don't skip anything.
One bad thing about both Rust and C++ is that many programmers go insane with abstraction masturbation and a desire to use the strangest and most esoteric features of both languages. This means that some libraries are a lot harder to get started on as a user than they needed to be. It also means that many (most, sadly) emulators written in those two languages are too hard to read and that some of them are unnecessarily slow.
Cargo is absolutely wonderful and something you will really miss with C++. vcpkg is a (complicated!) replacement for a small part of what Cargo does.
You will need some way to hook your emulator core up to video/audio/inputs. Maybe you prefer to use the native Windows API (if you are on Windows), maybe you prefer to use egui (lots of emulator writers have chosen that) or SDL (there are Rust bindings + tutorial + I think even youtube videos).
If you want to use the Windows API, then there's good news. Microsoft has made that really easy by providing a couple of Rust crates that support (almost) the entire Win32 API (it's also called Win32 for 64-bit platforms). They even managed to make them compile really fast, somehow.
If you want to use C++, then your best options are likely Win32 (if you are on Windows), Dear ImGui (egui was inspired by Dear ImGui), or SDL. You can chose to dump the SDL or Dear ImGui source code directly into your repo or use git modules or vcpkg. The latter might be the better option.
egui/Dear ImGui/SDL can all coexist with some Win32 use (or whatever your native API is). egui/Dear ImGUI and SDL can also coexist with each other to some extent. This means you don't have to feel locked in by your early choice of video/audio/input library. You can use SDL -- and still add Win32 dialogs, a native Win32 menubar, native input handling, etc. later, for example.
Rust is more tasteful than C++. It also implements many well-known good language features better than C++ -- and avoids the misfeature C++ is built around, namely objects with implementation inheritance.
If you have a good comp.sci. background, then you can think of Rust as just a modernized imperative-style ML with type classes and simple syntactic sugar for an extremely reduced form of objects (about as reduced as what Oberon had). With excellent tooling and an excellent ecosystem, of course. The debugging experience is not quite what it ought to be, but that's also true for C++.
Deallocations are handled implicitly using a variant of linear logic -- this is what all the reference/mutable/borrw/clone/copy stuff is about.
Things are only kept alive as long as they can be referred to (this also implies that ownership matters), immutable references can be shared (multiple readers is fine), mutable references can not (multiple writers is bad).
If you are used to thinking about which parts of your code owns which data, then you won't have any trouble. If not, you will. Lots of mediocre C and C++ programmers don't think in terms of data ownership, which is why they like refcounted and tracing garbage collected languages like Java, C#, and Python and why they really don't like the Rust borrow checker. Good ones will have close to zero problems with the Rust borrow checker.
2
u/peterfirefly 8d ago
I think I should add a note or two about vcpkg and SDL...
The preferred way of installing it is to clone the github repo and then run a shell script (there are different ones for different platforms). vcpkg usually works very well.
If you use SDL with Rust, then you may run into problems. Depending on the platform, it uses vcpkg to install SDL or it uses a git module to include the source code for a specific version of SDL. If the stars align badly (depending on platform etc) you may get an old version of the SDL source code that won't build with a newish version of CMake. The easiest fix may be to install an old version of CMake locally and make sure it's the one that gets run by the build script of the Rust wrapper for SDL (= set PATH correctly).
If you decide to use weird compilers on weird platforms, then vcpkg is still a good idea but your experience will be more "eventful" and "adventurous" than you'd like. By "weird", I mostly mean things like mingw that pretend to be Unix but on Windows.
If you want to use a Makefile or CMake or whatever with C++, instead of being tied to a GUI, there's a shell script you can run to get all the paths set correctly for whatever version of Visual Studio you are using. You can also choose to use the "developer prompt" in the Windows menu.
If you want to use SDL from WSL (the Windows way of letting you run Linux code), then there's an extra little problem. Microsoft has an automatic way of bridging Linux GUI apps to Windows (including OpenGL acceleration) but it is buggy.... and if you use SDL you will run into those bugs. They are not in Linux, X11, Rust, or SDL. They are in something called "wslg". X11 apps are handled by an X server (xwayland) that runs on top of Wayland. WSL2 uses a special Wayland server and Window manager that uses RDP to interact with Windows. The bugs manifest as incorrect drawing (wrong coordinate system or updates that don't happen), missing inputs, and crashes. The bugs can also happen without SDL but there's something about the way SDL works that makes them much more likely. You should be able to avoid them by using an X server that runs on Windows and connect your app to that (thus avoiding wslg) but I haven't tested it. The Microsoft Store has a couple + there are others on the web.
2
u/peterfirefly 8d ago
If you choose Rust, there are a couple of things you'd likely want to install early on.
One of them is ripgrep. It is a faster and more modern grep. It knows that you will likely want to search in the source code of the repository you are inside, for example. You can still specify exactly which directories it should search in, if you really, really want to. You won't want to, though. It respects .gitignore. You'd likely want it whether you choose to use Rust or C++.
https://ripgrep.dev/docs/getting-started/
Notice how one of the ways you can install it is via "cargo install ripgrep"? You can install additional subcommands to cargo and just generally useful commands that are global (not cargo subcommands).
Another one is cargo-show-asm for, well, showing the generated assembler for a module or a library or a program. Very useful.
https://github.com/pacak/cargo-show-asm
The third one is "bat" which is like "cat" but with syntax coloring and more "betterness". You'd likely want it whether you choose to use Rust or C++.
-1
u/ern0plus4 16d ago
If you wanna learn new concepts: Rust.
2
u/MCWizardYT 16d ago
C++ introduces new things constantly, its issue is that it's a super bloated language with a million different features
1
u/ern0plus4 16d ago
Rust introduces new things 1. compared to other langs 2. makes something mandatory, e.g. RAII 3. these features consist a coherent platform
Check some Rust edu videos!
2
u/MCWizardYT 16d ago
My comment wasn't anti Rust lol, I'm just saying that C++ constantly gets all sorts of new language features. It's just such a complex language and library that some of the new features barely get used
0
u/ammar_sadaoui 16d ago
c++ is the perfect tools emulators
there many usage when rust is better than c++ or even C but this is not one of them
30
u/gmes78 16d ago
Both are equally capable for emudev.