2 questions about declarative macros from a beginner in macros

N1.

Why isn't this code compiled,

fn main(){
    useless!()
}

macro_rules! useless{
    ()=>{
        
    }
}
error: cannot find macro `useless` in this scope
 --> src/main.rs:2:5
  |
2 |     useless!()
  |     ^^^^^^^
  |

does this mean that macros can't be used without #[macro_export] in general?!!?! And does this mean that there are no private macros for the module or crate?

N2.

Why isn't this code compiled,

fn main() {
    let c = useless!();
}

#[macro_export]
macro_rules! useless {
    () => {
        3;
        println!("three")
    };
}
error: macro expansion ignores token `println` and any following
 --> src/main.rs:9:9
  |


2 |     let c = useless!();
  |             ---------- caused by the macro expansion here
...
9 |         println!("three")
  |         ^^^^^^^
  |
  = note: the usage of `useless!` is likely invalid in expression context

Why doesn't this code work?!?!!!?, and for some reason macro expansion shows this code,

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
    let c =
        3;
}
#[macro_export]
macro_rules! useless { () => { 3 ; println! ("three") } ; }

but logically it was supposed to give out`

#![feature(prelude_import)]
#[prelude_import]
use std::prelude::rust_2021::*;
#[macro_use]
extern crate std;
fn main() {
    let c =3;
println! ("three") 
}
#[macro_export]
macro_rules! useless { () => { 3 ; println! ("three") } ; }

what is the reason for this behavior?

Because the macro definition doesn't precede its use.

No. But there's no need for "?!!?!".

No.

The macro expansion should result in a single syntactic unit. So if it's invoked in expression position, it should yield an expression, not in an expression and trailing garbage. That is enforced in order to prevent logic bugs resulting from such "clever" expansions.

Macros are not a string cut-and-paste device like they are in C. They operate at the AST level, their input and output is structured. You can't just emit random tokens.

thank you for answer, and really, if I do that, everything works :sweat_smile:,

macro_rules! useless {
    () => {
()
    };
}

fn main() {
    let c = useless!();
}
//works fine!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.