c - 出现错误 : expected declaration specifiers or '...' before string constant

标签 c gcc compiler-errors macros

我正在尝试创建一个日志函数,它将采用日志类型、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)) ===|

我读过这篇文章question但我无法将解决方案与我的代码联系起来。

最佳答案

您的代码可能合理地是:

#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);
    printf("%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__有东西可以引用。请参阅#define macro for debug printing in C进行广泛的讨论。最简单的可移植修复可能是更改宏以包含格式字符串作为 __VA_ARGS__ 的一部分。

#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 也解决了该问题并产生了不同的解决方案(请参阅 Portably detect __VA_OPT__ support? ),该解决方案我预计它可能会出现在未来的 C 标准中(以及在假设的 future C 标准之前的 C 编译器中)。

关于c - 出现错误 : expected declaration specifiers or '...' before string constant,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59517313/

相关文章:

c++ - gdb 无法监视在 for 循环内声明的变量

c - 使用 arm-none-eabi 工具链时重新定义 fputc 函数

c++ - 从另一个类 C++ 访问对象

gcc - GCC 下缺少返回语句的错误

c - 使用 MPI_Isend 和 MPI_Irecv 而不是 MPI_Bcast 为所有处理器定时广播消息

c - sleep() 背后的算法是什么?

c++ - 宏 C 中的字符串连接

Python扩展模块段错误

memory - 内在 memcmp

MySQL C API 编译错误,找不到 crtdbg.h