【问题标题】:Macro auto-injecting argument without VARIADIC support不支持 VARIADIC 的宏自动注入参数
【发布时间】:2015-06-11 19:35:37
【问题描述】:

我有一个带有可变参数的宏,它自动注入一些参数,比如下面的第一个注入参数“__FNAME__”:

#ifdef VERBOSE
#define logdbg(format, ...) debugff(__FNAME__, format, ##__VA_ARGS__)
#elif defined(NORMAL)
#define logdbg(format, ...) debugf(format, ##__VA_ARGS__)
#else
#define logdbg(format, ...) /* debud off */
#endif

但我需要让这个宏与不支持 MACRO VARIADIC 的编译器一起工作(在 SCO Unix 和 AIX 4.3 Copmiler v3 中)。

我现在在这些环境中:

#ifdef VERBOSE
#define logdbg debugff(__FNAME__, format, ##__VA_ARGS__)
#elif defined(NORMAL)
#define logdbg debugf
#else
#define logdbg if(1);else debugf
#endif

这些编译器不接受最后一个宏定义中的注释,我从https://stackoverflow.com/a/687412/926064 得到了可以正常工作的if(1);else blablabla

但我还需要一个解决方案来解决第一种情况,即参数被宏“注入”。

一些解决方法可以做到这一点?

编辑:

由于它不是支持多线程的软件,我正在考虑更改调试“框架”以使用辅助函数注入参数来设置“上下文”变量(全局、静态等)中的值:

#define logdbg pass_args(__FNAME__); debugf

更多可能的解决方法?

【问题讨论】:

  • 旁注:logdbg if(1);else debugf 看起来没什么好处(您可以将其包装成 do { ... } while(0)
  • 在这些平台上安装一个体面的编译器——例如 GCC。应该会更快吧。请注意,##__VA_ARGS__ 符号已经是 GCC 特定的;它不适用于任何其他编译器。其实,说到这里,__FNAME__ 也不是标准的 C。
  • @JonathanLeffler:安装其他编译器不是一种选择。
  • 只安装一个现代 CPP(C 预处理器)并在编译代码之前使用它怎么样?你在一个非常粘的检票口上。该代码使用的功能在标准的最旧版本 C89/C90 中没有对应功能。它是 C99 中的一个有价值的补充,因为它允许您完成以前无法完成的事情。
  • @DieterLücking “看起来没什么好”......确实。我想你可能稍微低估了这一点。一点点……

标签: c++ c unix macros c89


【解决方案1】:

假设 不可能 使用不同的编译器(这似乎是一个可疑的要求,但让我们把它放在一边),当然,您将需要一个不同的函数logdbg 展开成。很可能,该函数会从另一个来源(如全局变量)获取 __FNAME__ 参数。

#define logdbg ((logdbg_fname__ = __FNAME__), debugff_broken)

void debugff_broken(const char *fmt, ...) {
    extern const char *logdbg_fname__;
    va_list ap;
    va_start(ap, fmt);
    vdebugff(logdbg_fname__, fmt, ap);
    va_end(ap);
}

vdebugffdebugff 类似,但它需要 va_list

如果需要线程安全,请使用线程特定存储而不是通用全局。

【讨论】:

  • 您不能像在笔记本电脑上那样轻松更改某些旧环境的某些策略和治理来安装或更改系统中的所有内容。你所拥有的只是一个老式的 vi 和一个“驻留”的 C 编译器,仅此而已。您的方法是我正在使用的方法,但我需要确保只有一个线程。
  • 您可以使用来自 Solaris 线程 API 或 POSIX API 的线程特定存储。对于编译器,您可以将编译器作为构建过程的一部分进行编译,而不是将其安装在系统上。
  • 相信,我们有很多限制,包括工作fs中的存储空间,因为它是一个生产环境。
  • 我不知道我以前见过一家公司不愿意为构建服务器购买另一个磁盘。
  • 一家仍在使用 AIX 4.3.x 的公司非常吝啬。这已经过时了(就像完全失去支持一样)十年或更长时间(AIX 5.1 在 2006 年就失去了支持;IBM 的网站不再列出 AIX 4.3 — 我确实找到了 2003 年 12 月末的参考资料)。我不确定SCO Unix;它的识别不够清楚,但它也可能相当陈旧——因此是 C89 编译器。
猜你喜欢
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-16
  • 2012-04-01
相关资源
最近更新 更多