C99 宏在评估后构建带引号的字符串文字
我正在 C99 中开发一个嵌入式应用程序,该项目包含一些定义如下的整数常量:
#define LEVEL1 0x0000
#define LEVEL2 (LEVEL1 + 1)
从那时起,跟踪这些值以用于记录目的变得很有用,因此我想使用宏从上述的评估版本。例如:
strncpy(str, STRING(LEVEL2), len);
理想情况下会计算为
strncpy(str, "0x0001", len);
或什至
strncpy(str, "0001", len);
使用带有 # 运算符的两阶段宏(如 这个问题)几乎有效。它的评估结果是
strncpy(str, "(LEVEL1 + 1)", len);
我想避免使用运行时函数 - 因此我尝试使用宏解决方案。建议?
I'm developing an embedded application in C99, and the project contains some integer constants defined like:
#define LEVEL1 0x0000
#define LEVEL2 (LEVEL1 + 1)
It has since become useful to keep track of these values for logging purposes, so I would like to use a macro to create a string literal from the evaluated versions of the above. For example:
strncpy(str, STRING(LEVEL2), len);
would ideally evaluate to
strncpy(str, "0x0001", len);
or even
strncpy(str, "0001", len);
Using a two-stage macro with the # operator (as suggested by this question) almost works. It evaluates to
strncpy(str, "(LEVEL1 + 1)", len);
I would like to avoid the use of a run-time function - hence my attempt at a macro solution. Suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于预处理器字符串生成器非常痛苦,因此您需要在创建版本号和字符串化时添加一定程度的间接:
Since the pre-processor stringizer is a massive pain, you need to add a level of indirection both when creating version numbers and when stringizing:
您不能这样做,因为预处理器对 C 语言一无所知,因此无法进行评估。
我看到有两种选择可以获得所需的结果:
手动评估
完全按照您希望的显示方式编写级别并使用单个字符串生成器运算符:
缺点是这很容易出错,并且可能与本地编码约定发生冲突。
运行时评估
使用字符串格式函数
sprintf
或snprintf
之一。这具有您想要避免的运行时开销。
You cannot do this because the preprocessor knows nothing about the C language so it cannot to evaluation.
I see two options to get the desired result:
Manual evaluation
Write your levels exactly as you want them to appear and use a single stringizer operator:
A disadvantage is that this is error prone and might clash with local coding conventions.
Runtime evaluation
Use one of the string format functions
sprintf
orsnprintf
.This has the runtime overhead you wanted to avoid.