【问题标题】:C99 Macro to build a quoted string literal after evaluationC99 宏在评估后构建带引号的字符串文字
【发布时间】:2010-07-28 03:20:52
【问题描述】:

我正在用 C99 开发一个嵌入式应用程序,该项目包含一些整数常量,定义如下:

#define LEVEL1     0x0000
#define LEVEL2     (LEVEL1 + 1)

从那时起,为了记录目的而跟踪这些值变得很有用,所以我想使用一个宏从上面的 评估 版本创建一个字符串文字。例如:

strncpy(str, STRING(LEVEL2), len);

理想情况下评估为

strncpy(str, "0x0001", len);

甚至

strncpy(str, "0001", len);

使用带有# 运算符的两阶段宏(如this question 所建议的那样)几乎可以工作。它评估为

strncpy(str, "(LEVEL1 + 1)", len);

我想避免使用运行时函数 - 因此我尝试使用宏解决方案。有什么建议吗?

【问题讨论】:

    标签: string macros c99 literals expansion


    【解决方案1】:

    由于预处理器字符串化器是一个巨大的痛苦,您需要在创建版本号和字符串化时添加一个间接级别:

    #define STRING1(s) #s
    #define STRING(s) STRING1(s)
    
    #define LEVEL(x) x
    #define LEVEL1 LEVEL(1)
    #define LEVEL2 LEVEL(2)
    
    printf(STRING(LEVEL2));
    //2
    

    【讨论】:

      【解决方案2】:

      你不能这样做,因为预处理器对 C 语言一无所知,所以它不能进行评估。

      我看到两个选项来获得所需的结果:

      人工评估

      完全按照您希望它们出现的方式编写您的关卡并使用单个字符串化操作符:

      #define LEVEL1 0x0000
      #define LEVEL2 0x0001
      #define STRING(x)   # x
      
      strncpy(str, STRING(LEVEL2), len);
      

      一个缺点是这很容易出错并且可能与本地编码约定冲突。

      运行时评估

      使用字符串格式函数sprintfsnprintf 之一。

      #define LEVEL1 0x0000
      #define LEVEL2 0x0001
      
      char level[7];
      snprintf(level, sizeof level, "%#06x", LEVEL2);
      strncpy(str, level, len);
      

      这具有您想要避免的运行时开销。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-07-04
        • 2018-11-08
        • 2010-11-05
        • 2012-06-29
        • 2012-10-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多