开发者社区> 问答> 正文

收到错误:字符串常量之前的预期声明说明符或“ ...”

我试图创建一个将采用日志类型msg的日志函数,并将添加文件名,函数名,从中调用日志函数的行。我创建了以下测试代码,但收到了我不理解的错误

#include<stdio.h>

#define func(type, msg, ...) func(type, __FILE__, __func__, __LINE__, msg, __VA_ARGS__)

void func(int type, const char *file, const char *function, int line, const 
          char *msg, ...)
{
     printf("%s",msg);
}

main()
{
    func(10,"time");
}

这是错误日志:

||=== Build file: "no target" in "no project" (compiler: unknown) ===|
E:\code\C code\A.c|6|error: expected declaration specifiers or '...' before string constant|
E:\code\C code\A.c|3|error: expected declaration specifiers or '...' before '__func__'|
E:\code\C code\A.c|6|note: in expansion of macro 'func'|
E:\code\C code\A.c|6|error: expected declaration specifiers or '...' before numeric constant|
E:\code\C code\A.c|6|warning: type defaults to 'int' in declaration of 'msg' [-Wimplicit-int]|
E:\code\C code\A.c|3|note: in definition of macro 'func'|
E:\code\C code\A.c|12|warning: return type defaults to 'int' [-Wimplicit-int]|
E:\code\C code\A.c||In function 'main':|
E:\code\C code\A.c|3|warning: implicit declaration of function 'func' [-Wimplicit-function- 
declaration]|
E:\code\C code\A.c|15|note: in expansion of macro 'func'|
E:\code\C code\A.c|3|error: expected expression before ')' token|
E:\code\C code\A.c|15|note: in expansion of macro 'func'|
||=== Build failed: 4 error(s), 3 warning(s) (0 minute(s), 0 second(s)) ===|

我已经阅读了这个问题,但是无法将解决方案与我的代码联系起来。

展开
收起
几许相思几点泪 2019-12-29 20:43:19 4184 0
1 条回答
写回答
取消 提交回答
  • 您的代码可能合理地是:

    #include <stdio.h>
    #include <stdarg.h>
    #include <time.h>
    
    extern void (logger)(int type, const char *file, const char *function, int line, const char *fmt, ...);
    
    #define logger(type, msg, ...) logger(type, __FILE__, __func__, __LINE__, msg, __VA_ARGS__)
    
    void (logger)(int type, const char *file, const char *function, int line, const char *fmt, ...)
    {
        va_list args;
        va_start(args, fmt);
    p```  
    rintf("%s:%d:%s() - %d: ", file, line, function, type);
        vprintf(fmt, args);
        va_end(args);
    }
    
    int main(void)
    {
        logger(10, "time %ld\n", (long)time(0));
    }
    需要额外的参数,以便__VA_ARGS__引用。有关广泛的讨论,请参见#defineC中的调试打印宏。最简单的可移植修补程序可能是更改宏,以将格式字符串包含为__VA_ARGS__。
    
    ```js
    #define logger(type, ...) logger(type, __FILE__, __func__, __LINE__, __VA_ARGS__)
    
    

    进行此更改后,您可以再次使用此功能:

    int main(void)
    {
        logger(10, "time\n");
    }
    
    

    最好将人们将使用的宏名(logger)与函数名分开(例如logger_loc,带有loc指示“位置”的信息)。但是,(logger)(10, "elephants.c", "pachyderm", 31921, "time\n");如果他们希望直接调用该函数,则可以进行编写。因为logger没有紧随其后的是(令牌,所以它不是对类似于函数的宏的调用logger。

    还有一个针对“缺失__VA_ARGS__”问题的特定于GCC的解决方法,C ++ 20也已针对该问题进行了工作,并提出了不同的解决方案(请参阅可移植检测__VA_OPT__支持?),我希望该解决方案可能会在将来的C语言中出现。标准(以及在该假想的未来C标准之前的C编译器中)。

    2019-12-29 20:44:16
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载