【问题标题】:How to use __VA_ARGS__ variadic in 8051如何在 8051 中使用 __VA_ARGS__ 可变参数
【发布时间】:2022-01-18 06:32:31
【问题描述】:

我正在尝试在 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

请帮我修复此代码,谢谢。

【问题讨论】:

    标签: 8051


    【解决方案1】:

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

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

    #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 年前的标准更新的一些标准。

    【讨论】:

    • 但是当我有多个参数时,它会打印第一个参数并忽略剩余参数。示例:LOGI("Hello %u %u",1 , 2); 打印 1 并忽略 2
    • 不,请注意双括号。 -- 不管怎样,我再补充一个建议​​。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-03
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 2014-09-01
    • 1970-01-01
    • 2021-05-23
    相关资源
    最近更新 更多