Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C递归预处理器定义_C_Android Ndk_C Preprocessor - Fatal编程技术网

C递归预处理器定义

C递归预处理器定义,c,android-ndk,c-preprocessor,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

我已经将
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__)
预处理后的上一行看起来:

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]);
谁能解释一下:

  • c预处理器支持递归宏吗
  • LOG\u标记
    define被替换,而内部
    fprintf
    没有被替换,这是怎么回事
  • 这会定义任何地方的工作吗
  • 这到底是不是一个好办法
  • 不,c预处理器不“支持”递归宏,在您的例子中,这意味着它完全执行您想要的操作,而不是递归地扩展宏(它永远不会终止)
  • 预处理器不会扩展先前在当前扩展中已扩展的令牌
  • 我想是的。根据,这种行为似乎是ISO C标准的一部分(其中“传统模式”指ISO C89标准之前使用的模式)
  • 我觉得这很明智

  • 我只回答问题4。mstorsjo把剩下的都录了下来

    不,这不是个好主意。如果有另一种“适当”的方法来实现结果,则通常不鼓励使用宏魔术——可能是常量或函数(如本例所示)

    在这种情况下,对
    fprintf
    的调用(通常)返回
    int
    (输出的字符数)将不会计算为该值。例如,
    intcount=fprintf(文件“Hello”)将是一个编译错误

    这对您来说可能不是问题,但考虑到一般情况,任何在翻译单元中有任何代码(包括宏定义)的人都可能只是因为代码被破坏,而不得不寻找原因,然后需要取消宏定义才能取回代码

    马科斯还不错。特别是在条件编译和调试中,它们肯定占有一席之地。就我个人而言,在Java中,我非常想念他们

    然而,作为一般规则,如果有另一种语言结构来做同样的事情——使用它

    这里有一些极好的答案讨论了宏的优缺点:


    很简单,C预处理器没有递归宏。()
    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]);