【问题标题】:Nested macro calls嵌套宏调用
【发布时间】:2019-11-25 05:53:43
【问题描述】:

尝试嵌套宏调用如下:

#include <stdint.h>

#define INT
#define LONG

#define AS(t) AS_##t
#define AS_INT as_int
#define AS_LONG as_long

#define LET(v, t) v. AS(t)

typedef union
{
    int32_t as_int;
    int64_t as_long;
} mytype_t;

int main()
{
    mytype_t s;

    s.AS(INT) = 10;    /* This is OK */

    LET(s, INT) = 10;  /* This makes error */

    return 0;
}

出错了:

main.c:xx:yy: error: ‘mytype_t {aka union <anonymous>}’ has no member named ‘AS_’
 #define LET(v, t) v. AS(t)
                    ^
main.c:zz:ww: note: in expansion of macro ‘LET’
     LET(s, INT) = 10;
     ^~~

LET(s, INT) = 10; 有什么解决方法吗?

【问题讨论】:

  • 你为什么使用宏?似乎使代码更不可读,更难以调试。
  • 在包含LET(s, INT) = 10; /* This makes error */的行之前尝试#undef INT
  • 我知道这些技巧对他们有一定的吸引力,有点像定义特定领域的语言,但请考虑直接使用s.as_int 而不是通过这些宏。未来的读者,可能包括你未来的自己,会感谢你... =)

标签: c macros c-preprocessor c99


【解决方案1】:

就是这两个

#define INT
#define LONG

INT 通过LET 传递到AS(t) 时会进行中间扩展,并在AS() 本身扩展之前扩展为空令牌序列。因此,您将 AS_ 与空标记序列连接起来。只需删除这两个宏,为您的示例定义 AS_INTAS_LONG 就足够了。

【讨论】:

    【解决方案2】:

    已回答错误是由于空宏引起的。

    另一种解决方案可以是:

    #define INT INT
    #define LONG LONG
    

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 2013-03-13
      • 1970-01-01
      • 2021-11-25
      • 1970-01-01
      • 1970-01-01
      • 2013-12-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多