我有以下macros
#define REG_PWR_CTRL 0x2D #define REG_FIFO_CTL 0x38 #define VERBOSE(...) if(verbose) printf(__VA_ARGS__); #define READ_REGISTER(i2c_dev_file,REGISTER,variable) { variable = i2c_smbus_read_byte_data(i2c_dev_file,REGISTER); } #define WRITE_REGISTER_VERBOSE(i2c_dev_file,value) { short int var = 0; i2c_smbus_write_byte_data(i2c_dev_file,value); usleep(100); READ_REGISTER(i2c_dev_file,var); VERBOSE(#REGISTER " :0x%02Xn",var); }
我希望REGISTER字段不能在下面的行中展开
VERBOSE(#REGISTER " :0x%02Xn",var);
例如,当我写
WRITE_REGISTER_VERBOSE(i2c_dev_fd,REG_PWR_CTRL,0x1A);
WRITE_REGISTER_VERBOSE(i2c_dev_fd,REG_FIFO_CTL,0xC6);
我得到输出
0x2D :0x1A
0x38 :0xC6
我想获得
REG_PWR_CTRL :0x1A
REG_FIFO_CTL :0xC6
我遇到了很多关于增加额外间接级别的post。
我尝试了这里描述的答案https://stackoverflow.com/a/2653351/1761555虽然我相信这个答案是完全不同的问题..
如何在Windows控制台中禁用回声?
Linux / C ++如何debugging发布应用程序
在Windows中加载Qt中的外部DLL
为什么这个C程序在Windows上崩溃,并在Linux上正常工作?
用本地configuration文件replaceMicrosoft.VC90.CRT WinSxS策略文件
我做的是
#define STRINGIFY(label) (#label) #define WRITE_REGISTER_VERBOSE(i2c_dev_file,var); VERBOSE("%s :0x%02Xn",STRINGIFY(REGISTER),var); }
但是这仍然给我和以前一样的输出
有没有办法做到这一点?
奇怪的分析结果与zlib
我可以加快自己的应用程序build设吗(优化到目标平台)?
mono.unix.native在哪里?
在Windows上相当于PTHREAD_MUTEX_INITIALIZER?
您可以使REG_PWR_CTRL和REG_FIFO_CTL值为某些枚举,如
enum registers_en { REG__NONE,REG_PWR_CTRL = 0x2d,REG_FIFO_CTL = 0x38,};
然后, REG_PWR_CTRL成为一些枚举值的真实标识符,而不是在其他东西中进行宏扩展(因为enum定义不是宏定义,并且不由cpp预处理器处理 )。
因此,定义这样一个枚举,并预处理您的源代码(例如使用gcc -C -E yoursource.c > yoursource.i ),然后在预处理文件中查看(例如使用less yoursource.i )。 所有出现的REG_PWR_CTRL将仍然在那里。
请注意,预处理器在概念上是编译器的第一个阶段:即使在像GCC 4.8这样的编译器中,预处理器不是外部程序,而是通过libcpp内部库实现,编译器通过首先预处理源代码并获得流的词位 ,然后出现的REG_PWR_CTRL保持为词位(不像当你#define REG_PWR_CTRL 0x2d …那样文字常量为#define REG_PWR_CTRL 0x2d )。
您需要阅读更多关于预处理器cpp的信息 ,并习惯于查看预处理过的表单。
enum -s的另一个优点是,如果你用调试信息(例如gcc -g )编译调试信息,那么调试器gdb知道enum 。
#include <stdio.h> #define REG_PWR_CTRL (0x2D) #define GET_VAR_NAME(var) (#var) #define VERBOSE(...) (printf(__VA_ARGS__)) #define ANOTHER_LAYER(arg) ( VERBOSE("%s = %#X; %s = %#Xn",GET_VAR_NAME(REG_PWR_CTRL),GET_VAR_NAME(arg),arg) ) int main(void) { int num = 5; VERBOSE("%s = %#Xn",REG_PWR_CTRL); ANOTHER_LAYER(num); return 0; }
输出:
REG_PWR_CTRL = 0X2D REG_PWR_CTRL = 0X2D; num = 0X5
使用宏来做简单的事情。
这是因为:
你有更可读的代码
调试器有符号帮助你,因此更容易调试
他们很难调试。
所以只需使用复杂的东西的功能。 使用宏来做简单的事情
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。