C递归预处理器定义

标签 c android-ndk c-preprocessor

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

我不想大量修改代码所以我写了一个宏来登录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),它看起来像我预期的那样

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-preprocessor 是否支持递归宏?
  2. LOG_TAG 定义被替换但内部 fprintf 没有被替换是怎么回事?
  3. 这个定义是否适用于所有地方?
  4. 这是一个好方法吗?

最佳答案

  1. 不,c 预处理器不“支持”递归宏,在您的情况下这意味着它完全按照您的意愿行事,而不是递归地扩展宏(永远不会终止)。
  2. 预处理器不会在当前扩展中扩展之前已经扩展过的标记。
  3. 我想是的。根据https://gcc.gnu.org/onlinedocs/cpp/Traditional-macros.html ,这种行为似乎是 ISO C 标准的一部分(其中“传统模式”是指在 ISO C89 标准之前使用的模式)。
  4. 我觉得这很合理。

关于C递归预处理器定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27123487/

相关文章:

c++ - 使用预处理器重新定义 for 循环

c++ - 通过来自不同模块的预处理器/模板生成列表/集合,并且必须在链接之前填写

c++ - logb() 和 ilogb() 有什么区别?

c - 定义结构 vector 并将其作为 C 中的指针传递 - 错误 : initialization from incompatible pointer type

Android NDK UnsatisfiedLinkError - 一个令人惊讶的原因

android - 带有 ndk 的 native 应用程序无法正常工作

linux - 如何在 Fedora 中安装 NDK?

c - 我怎样才能 LD_PRELOAD 我自己编译的库?

C - 指向 double 和 double 组的指针之间的细微差别。将一个转换为另一个?

unix - 如何获取文件中使用(或定义)的所有预处理器符号的列表?