Rust的宏可以像C预处理器宏一样扩展为十六进制数吗?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Rust的宏可以像C预处理器宏一样扩展为十六进制数吗?相关的知识,希望对你有一定的参考价值。

我正在寻找创建一个可以在C中执行此操作的Rust宏。

#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

文档和其他问题似乎不包括这种情况。

答案

不。

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),这可能会破坏目的。

以上是关于Rust的宏可以像C预处理器宏一样扩展为十六进制数吗?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Rust 的 FFI 中使用 C 预处理器宏?

可变参数宏包装器,扩展为使用与参数数量相对应的字符格式化字符串

如何在 C++ 预处理器宏中处理数组元素?

是否可以在 C 宏中放置条件预处理器?

我可以将 Enum 扩展为 Enum.GetValues() 吗? [复制]

define