This question already has answers here:
Evaluate preprocessor token before ## concatenation
(2 个回答)
3年前关闭。
我正在尝试使用 ## 预处理器运算符来确定要使用的女巫 GPIO。
这是我的代码:
gpioAddress 的期望值为 0x00AC (GPIO_Pin_4) 但编译器给出了这个错误: "GPIO_Pin_DIVIDE 隐式声明"。我想连接 GPIO_Pin_ 和 DIVIDE(a,b) 宏的结果
这是 gcc 的汇编输出(clang 给出了类似的结果):
为了完整起见,这里是 clang :
任何优秀的现代编译器都可以确定 gpioNumber 在特定 AST 期间不会更改,并且会正确替换常量。
所以不要试图超越编译器,它在优化方面比你好得多。
如果您对编译器在这方面的擅长程度感兴趣,我已经在 Godbolt 上加载了这段代码:
https://godbolt.org/g/EWjsHB
您可以深入了解代码的反汇编。那里的所有编译器都使用 -O 作为选项来优化这些东西。
(2 个回答)
3年前关闭。
我正在尝试使用 ## 预处理器运算符来确定要使用的女巫 GPIO。
这是我的代码:
#define GPIO_Pin_1 0x0001
#define GPIO_Pin_2 0x00CA
#define GPIO_Pin_3 0x00DE
#define GPIO_Pin_4 0x00AC
#define DIVIDE(a , b) ( (a) / (b) )
#define NUMBER_TO_GPIO(a) GPIO_Pin_##DIVIDE(a , 2)
int gpioNumber = 8;
int gpioAddress = NUMBER_TO_GPIO(gpioNumber);
gpioAddress 的期望值为 0x00AC (GPIO_Pin_4) 但编译器给出了这个错误: "GPIO_Pin_DIVIDE 隐式声明"。我想连接 GPIO_Pin_ 和 DIVIDE(a,b) 宏的结果
最佳答案
没有什么好的方法可以只用 CPP 来做你想做的事情。特别是因为您在运行时计算 GPIO 数量。
确保它在编译时直接替换的唯一方法是直接使用索引(您没有这样做)
将此视为 C 中的解决方案:
const long GPIO_PINS[] = { 0xFFFF, 0x0001, 0x00CA, 0x00DE, 0x00AC };
static inline long getGPIOAddr(int gpioAddress) {
return GPIO_PINS[gpioAddress >> 1];
}
int main() {
const int gpioNumber = 8;
return getGPIOAddr(gpioNumber);
}
这是 gcc 的汇编输出(clang 给出了类似的结果):
.file "foo.c"
.text
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
movl $172, %eax ; NOTICE THE OPTIMIZATION HERE!
ret
.cfi_endproc
.LFE1:
.size main, .-main
.globl GPIO_PINS
.section .rodata
.align 32
.type GPIO_PINS, @object
.size GPIO_PINS, 40
GPIO_PINS:
.quad 65535
.quad 1
.quad 202
.quad 222
.quad 172
.ident "GCC: (GNU) 7.2.0"
.section .note.GNU-stack,"",@progbits
为了完整起见,这里是 clang :
.file "foo.c"
.text
.globl main
.align 16, 0x90
.type main,@function
main: # @main
.cfi_startproc
# BB#0:
movl $172, %eax
ret
.Ltmp0:
.size main, .Ltmp0-main
.cfi_endproc
.type GPIO_PINS,@object # @GPIO_PINS
.section .rodata,"a",@progbits
.globl GPIO_PINS
.align 16
GPIO_PINS:
.quad 65535 # 0xffff
.quad 1 # 0x1
.quad 202 # 0xca
.quad 222 # 0xde
.quad 172 # 0xac
.size GPIO_PINS, 40
.ident "clang version 3.4.2 (tags/RELEASE_34/dot2-final)"
.section ".note.GNU-stack","",@progbits
任何优秀的现代编译器都可以确定 gpioNumber 在特定 AST 期间不会更改,并且会正确替换常量。
所以不要试图超越编译器,它在优化方面比你好得多。
如果您对编译器在这方面的擅长程度感兴趣,我已经在 Godbolt 上加载了这段代码:
https://godbolt.org/g/EWjsHB
您可以深入了解代码的反汇编。那里的所有编译器都使用 -O 作为选项来优化这些东西。
关于c++ - 将 ## 预处理器运算符与另一个宏输出一起使用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/48749778/