【问题标题】:Use C macro to create string with #使用 C 宏创建带有 # 的字符串
【发布时间】:2020-12-08 06:59:21
【问题描述】:

我正在使用微控制器并想编写一个插入特定数量的等待周期的宏。我想要

DELAY_CYCLES(40)

展开到

__asm(" RPT #40 || NOP");

附加限制:

  1. 由于这是特定于编译器的内在函数,因此它需要完全匹配。我不能依赖编译器来合并字符串。例如。 __asm(" RPT #""40"" || NOP"); 不正确。

  2. 制造商标头已定义:#define NOP __asm(" NOP")

  3. 我无法将字符串传递给内在函数。不允许使用char str = " RPT #40 || NOP"; __asm(str);

目前我什至不确定是否有解决这种特殊情况的方法。

【问题讨论】:

  • 快速提问:你试过__asm(" RPT #""40"" || NOP");吗?大多数编译器中的 __asm 语法都可以很好地处理这个问题。
  • @nneonneo 实际上不,我认为它不会起作用。我会试试。也许编译器比我想象的要聪明。
  • 这不是“聪明”的问题。字符串在预处理期间被连接,然后被解析。如果你打算用宏做一些奇怪的事情,你应该从学习如何使用预处理器开始,包括翻译的不同阶段。
  • @Sneftel 错误,迂腐修正,但它处理字符串合并的编译器。预处理器不这样做。 (自己检查:echo 'char *x = "a""b";' | gcc -xc -E -;这会打印出char *x = "a""b";
  • @nneonneo 它确实会影响字符串解析。例如。 "\x1234" 是无效的转义序列,但 "\x12""34" 可以编译。

标签: c c-preprocessor


【解决方案1】:

您的编译器很可能会正确连接字符串文字(尽管第 1 点);例如,GCC 和 Clang 会这样做。在这种情况下,简单的解决方案是以下宏:

#define DELAY_CYCLES(X) __asm(" RPT #" #X " || NOP");

但是,在极少数情况下,当你真的需要创建一个单个字符串时,你可能会考虑这样的一些hackery:

#define A(X) __asm(#X)
#define B(X) A(X || NOP)
#define HASH #
#define DELAY_CYCLES(X) B(RPT HASH X)

DELAY_CYCLES(40) 扩展为 __asm("RPT # 40 || NOP"),即使将 NOP 定义为其他内容。据我所知,#40 之间的空格不能用这种技术消除,除非您想编写 DELAY_CYCLES(#40) 或者您的预处理器允许您将 #40 粘贴在一起(GCC 不允许)。

【讨论】:

    猜你喜欢
    • 2010-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-03
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多