使用条件读取#define中的空指针

时间:2017-03-29 17:15:55

标签: c c-preprocessor

我定义了宏printerr

#define CLR_R "\x1b[1;31m" 
#define CLR_N "\x1b[0m"
#define printerr(caller,msg) (caller==NULL)?printf(CLR_R "%s" CLR_N "\n",msg) \
   : printf(CLR_R "%s:" CLR_N " %s\n",caller,msg)

并获得警告

  

警告:在调用printerr(NULL,"error");时读取空指针(参数2)。

如何取消此警告?

#include <stdio.h>
#define printerr(caller,msg) (caller==NULL)?printf("%s\n",msg) : \
    printf("%s: %s\n",caller,msg)
void main() {
    printerr("Error","error occurred"); //will be ok
    printerr(NULL,"error"); //Warning: is caller even checked here?
}

1 个答案:

答案 0 :(得分:1)

这有效(gcc,clang):

#include <stdio.h>
int main()
{
#define CLR_R "\x1b[1;31m" 
#define CLR_N "\x1b[0m"

#define printerr(caller,msg)  \
    (caller==NULL)? printf(CLR_R "%s" CLR_N "\n",msg) : \
    printf(CLR_R "%s:" CLR_N " %s\n", ((caller)?(caller):""),msg)


    printerr(NULL,"msg");
    printerr("caller","msg");
}

我使用((caller)?(caller):"")来抑制警告。它永远不会评估为""

你也可以使用内联函数来达到同样的效果:

#define CLR_R "\x1b[1;31m" 
#define CLR_N "\x1b[0m"
static inline int inl_printerr(char const *caller, char const *msg)
{
    if (caller)
        return printf(CLR_R "%s:" CLR_N " %s\n", caller,msg);
    else
        return printf(CLR_R "%s" CLR_N "\n",msg);
}

(推荐,因为它避免了宏所具有的安全性和双重评估问题)。