Могут ли макросы Rust расширяться как макросы препроцессора C для шестнадцатеричных чисел? - PullRequest
0 голосов
/ 06 сентября 2018

Я хочу создать макрос Rust, который может делать то же, что и в C.

#define V(a,b,c,d) 0x##a##b##c##d

Который при вызове с:

V(7B,B0,B0,CB)

Во время компиляции будет просто помещено следующее шестнадцатеричное число в коде:

0x7BaB0bB0cCDd

Попытка что-то вроде этого:

macro_rules! gen_hex_num {
    ($a:expr , $b:expr , $c:expr , $d:expr) => (
        0x($a)a($b)b($c)c($d)d
    )
}

выдает ошибку:

error: macro expansion ignores token `a` and any following
 --> src/main.rs:3:16
  |
3 |         0x($a)a($b)b($c)c($d)d
  |               ^
  |
note: caused by the macro expansion here; the usage of `gen_hex_num!` is 
likely invalid in expression context

Документация и другие вопросы, по-видимому, не охватывают этот сценарий.

1 Ответ

0 голосов
/ 06 сентября 2018

Нет.

Макросы Rust могут обрабатывать и генерировать только целые токены, а не фрагменты токенов.Что-то вроде 7b не является токеном, поэтому вы не сможете написать макрос, который бы ему соответствовал.

Кажется, что основная причина использования этого макроса в C состоит в том, чтобы сделать число болееудобочитаемый.В Rust это не обязательно, потому что в числовых литералах допускается подчеркивание.Таким образом, вы можете просто написать 0x7b_b0_b0_cb.

Вы можете аппроксимировать исходный макрос, принимая числа и делая математику, что-то вроде следующего:

macro_rules! gen_hex_num {
    ($a:expr, $b:expr, $c:expr, $d:expr) => {
        ($a << 24) | ($b << 16) | ($c << 8) | ($d)
    }
}

Но вы должны называть это какgen_hex_num!(0x7B, 0xB0, 0xB0, 0xCB), что, вероятно, побеждает цель.

...