58

Quoted from the Rust blog:

One last thing to mention: Rust’s macros are significantly different from C macros, if you’ve used those

What is the difference between macros and function in Rust? How is it different from C?

geckob
  • 7,680
  • 5
  • 30
  • 39

3 Answers3

55

Keep on reading the documentation, specifically the chapter on macros!

Rust functions vs Rust macros

Macros are executed at compile time. They generally expand into new pieces of code that the compiler will then need to further process.

Rust macros vs C macros

The biggest difference to me is that Rust macros are hygenic. The book has an example that explains what hygiene prevents, and also says:

Each macro expansion happens in a distinct ‘syntax context’, and each variable is tagged with the syntax context where it was introduced.

It uses this example:

For example, this C program prints 13 instead of the expected 25.

#define FIVE_TIMES(x) 5 * x

int main() {
    printf("%d\n", FIVE_TIMES(2 + 3));
    return 0;
}

Beyond that, Rust macros

  • Can be distributed with the compiled code
  • Can be overloaded in argument counts
  • Can match on syntax patterns like braces or parenthesis or commas
  • Can require a repeated input pattern
  • Can be recursive
  • Operate at the syntax level, not the text level
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
  • 26
    One thing this answer is missing to answer "What is the difference between macros and functions?" is "Why do we need functions at all?", as the answer seems to describe macros as having all the features of functions and more. – mcarton Jan 13 '20 at 13:32
  • 13
    I wasn't understanding why it was `5 * 2 + 3` instead of `5 * 5`. It's worth mentioning since most people probably won't read the link that `FIVE_TIMES(x)` will take `x` as the operation `2 + 3`, **not** the result of `2+3 = 5`. Plugging 2 + 3 in, then you get `5 * 2 + 3` and the order of operations gives you `5*2 = 10` and then `10 + 3 = 13`. So if you think in terms of strings, this is just an unevaluated substitution. – oooyaya Feb 16 '21 at 15:06
  • 1
    @mcarton presumably the answer is that you should prefer functions and limit macros to cases where it is unavoidable (e.g. variadic parameters). The reason being that "macro definitions are more complex" and so "generally more difficult to read" as the Rust docs and Vahin Sharma's answer explains – Tom Bailey May 24 '22 at 15:14
  • 1
    Which is why it is good to use extra parens in macros in C: #define FIVE_TIMES(x) (5 * (x)) – Aron Insinga Jun 29 '22 at 18:03
  • A shame that Rust macros are not type safe like macros/templates in Nim – Alexandre Daubricourt Apr 24 '23 at 07:56
32

Quoting from the Rust documentation:

The Difference Between Macros and Functions

Fundamentally, macros are a way of writing code that writes other code, which is known as metaprogramming. In Appendix C, we discuss the derive attribute, which generates an implementation of various traits for you. We’ve also used the println! and vec! macros throughout the book. All of these macros expand to produce more code than the code you’ve written manually.

Metaprogramming is useful for reducing the amount of code you have to write and maintain, which is also one of the roles of functions. However, macros have some additional powers that functions don’t.

A function signature must declare the number and type of parameters the function has. Macros, on the other hand, can take a variable number of parameters: we can call println!("hello") with one argument or println!("hello {}", name) with two arguments. Also, macros are expanded before the compiler interprets the meaning of the code, so a macro can, for example, implement a trait on a given type. A function can’t, because it gets called at runtime and a trait needs to be implemented at compile time.

The downside to implementing a macro instead of a function is that macro definitions are more complex than function definitions because you’re writing Rust code that writes Rust code. Due to this indirection, macro definitions are generally more difficult to read, understand, and maintain than function definitions.

Another important difference between macros and functions is that you must define macros or bring them into scope before you call them in a file, as opposed to functions you can define anywhere and call anywhere.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Levan
  • 616
  • 6
  • 10
2

In macro, you can take variable number of parameters.

In function you have to define number and type of parameters.

Ayush Mishra
  • 567
  • 1
  • 7
  • 19
  • 12
    Please clarify what this answer adds to the existing answers, which mention *Can be overloaded in argument counts* – Shepmaster Feb 24 '19 at 22:04