停止布尔的宏扩展

mie*_*dup 7 c macros c-preprocessor

通过宏实现功能是布尔的噩梦。我已经为(通用)函数的头部和主体定义了宏。使用布尔型时,结果很奇怪。

我知道,这通常是出于可维护性而需要避免的事情〜但就我而言,这是一组非常相似的回调函数和一个非常苛刻的缩写。

因此,目标实际上是可维护性和可读性,尤其是代码一致性。

#include <stdio.h>
#include <stdbool.h>

#define FUN_H(TYPE) \
  void fun_##TYPE( void )

#define FUN(TYPE) \
  FUN_H(TYPE) { \
    printf("Type is " #TYPE ".\n"); \
  }

FUN_H(int);
FUN_H(bool);

FUN(int);
FUN(bool);

int main(void) {
  fun_int();
  fun_bool();
}
Run Code Online (Sandbox Code Playgroud)

阅读代码,我期望输出“ Type is int”。和“类型是布尔”。

实际上,要使代码编译(当前gcc / clang),必须将最后一次调用更改为fun__Bool();,并将标头更改为FUN_H(_Bool);-如果您知道C99却产生不连贯的代码,这实际上是有意义的。


可能的解决方案

_Bool直接使用类型

FUN_H(_Bool);
FUN(_Bool); // or FUN(bool);

int main(void) {
  fun__Bool();
}
Run Code Online (Sandbox Code Playgroud)

专业人士

  • 没有足迹

缺点

  • 丑陋!
  • 两种方法定义相同的功能,但打印不同的输出

手动扩展FUN()

#define FUN(TYPE) \
  void fun_##TYPE( void ) { \
    printf("Type is " #TYPE ".\n"); \
  }
Run Code Online (Sandbox Code Playgroud)

专业人士

  • 其他宏类型的通用解决方案

缺点

  • 不符合DRY

typedef 对于 _Bool

typedef _Bool mybool;

FUN_H(mybool);
FUN(mybool);

int main(void) {
  fun_mybool();
}
Run Code Online (Sandbox Code Playgroud)

专业人士

  • 保守

缺点

  • 需要特殊类型的名称

更改booltypedef

#undef bool
typedef _Bool bool;

FUN_H(bool);
FUN(bool);

int main(void) {
  fun_bool();
}
Run Code Online (Sandbox Code Playgroud)

专业人士

  • 清洁

缺点

  • 可能会破坏奥术

那么,应该怎么办?

PSk*_*cik 5

如果是宏FUN_H,则扩展bool为内部宏调用。如果您丢失了内部宏,则直接这样写:_BoolboolFUN_HFUN

#include <stdio.h>
#include <stdbool.h>

#define FUN_H(TYPE) \
  void fun_##TYPE( void )

#define FUN(TYPE) \
  void fun_##TYPE( void ) { \
    printf("Type is " #TYPE ".\n"); \
  }

FUN_H(int);
FUN_H(bool);

FUN(int);
FUN(bool);

int main(void) {
  fun_int();
  fun_bool();
}
Run Code Online (Sandbox Code Playgroud)

那么您将获得fun_bool预期的结果,即使它bool是一个宏也是如此。

  • @ miehe-dup-然后将“ NAME”而不是“ TYPE”传递给“ FUN_H”。在调用方进行连接。这样,仅必须重复的最小位将被重复。 (2认同)

Sto*_*ica 3

如前所述,传递TYPE给任何中间宏将在进一步处理之前强制其扩展。因此,在传递任何地方之前,必须尽早进行串联TYPE。为了在不重复太多的情况下实现它,我们可以委托给第三个宏

#define FUN_H(TYPE) \
  FUN_H_(fun_##TYPE)

#define FUN_H_(NAME) \
  void NAME( void )

#define FUN(TYPE) \
  FUN_H_(fun_##TYPE) { \
    printf("Type is " #TYPE ".\n"); \
  }
Run Code Online (Sandbox Code Playgroud)