Hi,
I have this macro rule:
macro_rules! is_between {
($value:expr, $a:expr, $b:expr) => {
$value >= $a && $value <= $b
};
}
It's used in code like this:
pub fn to_phys_addr(mut virt_addr: u32) -> u32 {
if is_between!(virt_addr, 0x80000000, 0x9FFFFFFF) {
virt_addr -= 0x80000000;
}
if is_between!(virt_addr, 0xA0000000, 0xBFFFFFFF) {
virt_addr -= 0xA0000000;
}
if is_between!(virt_addr, 0x00000000, 0x03EFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x03F00000, 0x03FFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04000000, 0x040FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04100000, 0x041FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04200000, 0x042FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04300000, 0x043FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04400000, 0x044FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04500000, 0x045FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04600000, 0x046FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04700000, 0x047FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04800000, 0x048FFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x04900000, 0x04FFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x05000000, 0x05FFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x06000000, 0x07FFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x08000000, 0x0FFFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x10000000, 0x1FBFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x1FC00000, 0x1FC007BF) {
return virt_addr;
} else if is_between!(virt_addr, 0x1FC007C0, 0x1FC007FF) {
return virt_addr;
} else if is_between!(virt_addr, 0x1FC00800, 0x1FCFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x1FD00000, 0x7FFFFFFF) {
return virt_addr;
} else if is_between!(virt_addr, 0x80000000, 0xFFFFFFFF) {
return virt_addr;
} else {
panic!("Invalid virtual address {:x}", virt_addr);
}
}
This bring to two (valid) warnings in compiler:
warning: comparison is useless due to type limits
--> src/util_macro.rs:49:9
|
49 | $value >= $a && $value <= $b
| ^^^^^^
|
::: src/device.rs:118:12
|
118 | if is_between!(virt_addr, 0x00000000, 0x03EFFFFF) {
| ---------------------------------------------- in this macro invocation
|
= note: `#[warn(unused_comparisons)]` on by default
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
warning: comparison is useless due to type limits
--> src/util_macro.rs:49:25
|
49 | $value >= $a && $value <= $b
| ^^^^^^
|
::: src/device.rs:178:19
|
178 | } else if is_between!(virt_addr, 0x80000000, 0xFFFFFFFF) {
| ---------------------------------------------- in this macro invocation
|
= note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
I wanted to write macro so if $a constant is min, or $b constant is max, it follow a different path:
macro_rules! is_between {
($value:expr, $a:expr, $b:expr) => {
$value >= $a && $value <= $b
};
($value:expr, $a:expr:is_type_min(), $b:expr) => {
$value <= $b
};
($value:expr, $a:expr, $b:expr:is_type_max()) => {
$value >= $a
};
}
- How can I do that? Does it make sense?
- How would you write the
to_phys_addr()function?
I know I can replace the two conditions with single compare, but I wanted to keep the code explicit.
A big thanks in advance! ![]()