如何在 8051 中使用 __VA_ARGS__ 可变参数

How to use __VA_ARGS__ variadic in 8051

我正在尝试在 Keil IDE 中构建一个项目 8051。 我有一个打印信息的定义,用于调试程序,如下所示:

#define LOGI(fmt, ...)      printf("[I] %s:%u: "fmt, __FILE__, __LINE__, ##__VA_ARGS__)

但是有错误:

log.h(18): error C301: identifier expected
log.h(18): error C301: identifier expected
log.h(18): error C304: bad macro parameter list

请帮我修复这段代码,谢谢。

根据documentation,Keil C51是基于C90的。所以它不支持 C99 添加的 __VA_ARGS__

但是,您可以通过这个技巧来解决这个问题。使用带括号的参数。

#define LOGI(args) \
    do { \
        printf("[I] %s:%u: ", __FILE__, __LINE__); \
        printf args; \
    } while (0)

void f(void) {
    LOGI(("address of f() = %p\n", f));
}

另一种可能的解决方案是提供一个参数数量可变的自有函数,请参阅 example in the documentation。这是一种更简洁的方法,因为您可以在阅读源代码时使用此函数而不会因为双括号而出现“问题”。但请注意,这些参数并未放在寄存器中,而是使用了堆栈和代码中的更多内存。

#include <stdio.h>
#include <stdarg.h>

void logi(const char* filename, int line, char *fmt, ...) {
    va_list arg_ptr;
    va_start(arg_ptr, fmt);
    printf("[I] %s:%u: ", filename, line);
    vprintf(fmt, arg_ptr);
    va_end(arg_ptr);
}

void f(void) {
    logi(__FILE__, __LINE__, "Hello %u %u", 1 , 2);
}

注意:您可能想切换到另一个编译器,它支持比 30 年前的标准更新的标准。