this post was submitted on 19 Jan 2026
0 points (50.0% liked)
Rust
7684 readers
18 users here now
Welcome to the Rust community! This is a place to discuss about the Rust programming language.
Wormhole
Credits
- The icon is a modified version of the official rust logo (changing the colors to a gradient and black background)
founded 2 years ago
MODERATORS
you are viewing a single comment's thread
view the rest of the comments
view the rest of the comments
I'm not talking about what features are in the standard libraries vs third party libraries. I mean meta-programming as in the stuff that generates Rust code. Take console printing for example, we use a macro
println!in Rust. Other languages provide an actual function (e.g.printfin C,System.out.printlnin Java,printin Python, etc). The code for my first project is also full of things like#[derive(Debug,Default,Eq,PartialEq)]to get features that I normally achieve through regular code in other languages. These things are still in the Rust standard library as I understand it.printfuses macros in its implementation.^ This is from glibc. Do you know what
va_startandva_endare?Derives expand to "regular code". You can run
cargo expandto see it. And I'm not sure how that's an indication of "bare bone"-ness in any case.Such derives are actually using a cool trick, which is the fact that proc macros and traits have separate namespaces. so
#[derive(Debug)]is using the proc macro namedDebugwhich happens to generate "regular code" that implements theDebugtrait. The proc macro namedDebugand implemented traitDebugdon't point to the same thing, and don't have to match name-wise.Does anyone? 🙃
For functions that want to accept variadic arguments in C/Cpp
Yup; I was referring to their implementation being dark magic, depending on calling convention, argument type, argument order and possibly other properties specific to the processor’s instruction set…
“If you think you understand
va_*, you don’t.”Yeah, didn't catch your sarcasm there :D
I was just referring to the fact that they are macros.
Using a function is strictly worse than figuring out the formatting at compile time (something Zig also does).
The derives are just shortcuts. You can write everything out long-hand like you would in C++ or Python too if you really want.
Honestly both of these complaints are essentially "why does Rust use macros to make writing code better/easier?".
@cx40 @kornel using a macro ensure the format string and the values printed are typed correctly at compile time. It also ensure that most of the parsing is done at compile time and just the bare minimum is done at runtime. It's a safe and fast way to solve this issue.
Most high-level languages do a lot of things implicitly, like casting types, cloning values, deciding what the default is. Rust tends to avoid that, which though less convenient makes behavior more predictable, reducing footguns and surprises.
Regarding the derive macros, there are a few reasons these are required.