【问题标题】:How to escape a # in a macro如何在宏中转义 #
【发布时间】:2016-07-07 11:46:14
【问题描述】:

我需要编写一个需要内联汇编的宏

#define create_me(name) \
  __asm\
  mov name,#0x1021\
  __endasm\

但是 # 没有编译。我尝试将它作为参数传递,但这也不起作用。它说无效的预处理器令牌。我可以尝试使用内联函数,但无法动态创建寄存器名称。那就是我无权访问 name 变量。有没有人对如何在宏中使用 # 操作有任何建议。

我看过Escaping a # symbol in a #define macro?,但我已经清楚地解释了为什么我需要这里的宏。我的用例不同。

【问题讨论】:

  • SDCC,我想。 sdcc.sourceforge.net
  • 是的。 SDCC 3.5 版
  • 您可以选择以字符串格式执行内联汇编吗?如果是这样,只需将整个程序集转换为字符串。
  • 是的。那是在那里。我只是想知道是否可以这样做

标签: c macros c-preprocessor sdcc


【解决方案1】:

通过另一个宏使用间接应该可以解决问题:

#define HASH_LIT #
#define HASH() HASH_LIT

#define create_me(name) \
  __asm\
  mov name,HASH()0x1021\
  __endasm

【讨论】:

  • 我没试过。让我看看它是否编译
  • @losang 那是凭记忆,我忘记了一半。这是工作版本。
  • @n.m.,为什么这不起作用? gcc -E 为此产生所需的输出,正如我认为的那样。这是否以某种方式依赖于扩展?
  • @JohnBollinger 以前的版本不行,这个可以(而且我认为它是合法的),
【解决方案2】:

对于 SDCC,请使用新的 __asm__ 格式。

#define create_me(name) \
      __asm__( "mov "    #name    ", #0x1021" )

【讨论】:

    【解决方案3】:

    预处理器命令/指令始终以尖号 (#) 开头,您不能将其用于自己的符号。

    如果要创建一个名为 whatever0x1021 的变量,请使用 token concatenation ##

    #include <stdio.h>
    
    #define create_me(name) name ## 0x121
    
    int main(void)
    {
        int create_me(a); /* int a0x121; */
    
        return 0;
    }
    

    【讨论】:

    • 这个想法不是创建变量,而是使用内联汇编加载变量。
    【解决方案4】:

    这有助于了解问题的性质。 # 符号在三个方面对预处理器来说是特殊的:

    1. 第一个预处理标记为# 的源代码行被预处理器识别为不是“文本行”。也就是说,它包含预处理器的指令。另一方面,文本行是要处理的数据——主要是 C 程序源,但可能包含要扩展的宏。如果# 不是该行的第一个预处理标记,那么它在这个意义上并不特殊。

    2. 在类函数宏的替换列表的预处理标记中,标记# 是字符串化运算符。但是,它不适用于类似变量的宏,也不适用于重新扫描宏扩展文本以进行进一步的宏替换。

    3. 在类函数宏的替换列表的预处理标记中,标记## 是标记粘贴运算符。但是,它不适用于类似变量的宏,也不适用于重新扫描宏扩展文本以进行进一步的宏替换。

    您无法逃避# 对预处理器的重要性本身,但您仍然可以通过使用一些间接来实现所需的宏,正如@Quentin 所展示的那样。首先,如果# 出现在类似函数的宏的扩展中,那么它不能直接出现在该宏的替换文本中,在那里它将被解释为字符串化运算符。相反,它必须通过扩展另一个宏来引入。其次,如果它必须与其他没有空格的文本相邻,那么扩展到它的直接宏必须是类似函数的宏本身,以便括号用于将宏名称与相邻文本分开。这需要第二级间接。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-12
      • 1970-01-01
      • 2010-11-11
      • 2017-05-14
      • 2011-03-08
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多