C递归预处理器定义 [英] C recursive preprocessor define

查看:39
本文介绍了C递归预处理器定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已将 libiniparser 库合并到我的 Android NDK 应用程序中.该库将日志直接写入 stdout/stderr 的一个问题.

I have incorporated libiniparser library in to my Android NDK application. One problem this library write logs directly to stdout/stderr.

我不想大量修改代码所以我写了一个宏来登录logcat

I did not want to heavily modify the code so I wrote a macro to log in logcat

#include <android/log.h>

#define LOG_TAG   "libinipaser"

#define fprintf(pipe,...) \
    if (pipe == stdout) \
        __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__); \
    else if (pipe == stderr) \
        __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__); \
    else \
        fprintf(pipe,__VA_ARGS__)

直到最后一刻我都不确定它会起作用,但它起作用了.我已经检查了预处理器输出(gcc -E),它看起来像我预期的

Until the last moment I was not sure it would work, but it works. I have checked preprocessor output (gcc -E) it looks like I expected

fprintf(f, "[%s]=[%s]\n", d->key[i], d->val[i]);

预处理后的上面一行:

if (f == (&__sF[1])) __android_log_print(ANDROID_LOG_INFO,"libinipaser","[%s]=[%s]\n", d->key[i], d->val[i]); else if (f == (&__sF[2])) __android_log_print(ANDROID_LOG_ERROR,"libinipaser","[%s]=[%s]\n", d->key[i], d->val[i]); else fprintf(f,"[%s]=[%s]\n", d->key[i], d->val[i]);

谁能解释一下:

  1. c 预处理器是否支持递归宏?
  2. 为什么 LOG_TAG 定义被替换而内部 fprintf 没有被替换?
  3. 这个定义是否适用于任何地方?
  4. 这到底是不是一个好方法?
  1. Does c-preprocessor support recursive macros?
  2. How it happened that the LOG_TAG define was replaced but inner fprintf wasn't?
  3. Will this define works everywhere?
  4. Is this a good approach at all or not?

推荐答案

  1. 不,c 预处理器不支持"递归宏,在您的情况下,这意味着它完全符合您的要求,而不是递归扩展宏(永远不会终止).
  2. 预处理器不会扩展之前在当前扩展中已经扩展过的标记.
  3. 我想是的.根据 https://gcc.gnu.org/onlinedocs/cpp/Traditional-macros.html,这种行为似乎是 ISO C 标准的一部分(其中传统模式"是指在 ISO C89 标准之前使用的模式).
  4. 我觉得这很明智.
  1. No, the c preprocessor doesn't "support" recursive macros, which in your case means that it does exactly what you want, instead of expanding the macro recursively (which wouldn't ever terminate).
  2. The preprocessor doesn't expand tokens that already have been expanded previously in the current expansion.
  3. I think so. According to https://gcc.gnu.org/onlinedocs/cpp/Traditional-macros.html, this behaviour seems to be part of the ISO C standard (where the "traditional mode" means the mode that was used before the ISO C89 standard).
  4. It looks quite sensible to me.

这篇关于C递归预处理器定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆