V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
XIVN1987
V2EX  ›  C

C 中可变参数如何直接传递到 printf()

  •  
  •   XIVN1987 · 2024-11-12 17:41:03 +08:00 · 3285 次点击
    这是一个创建于 390 天前的主题,其中的信息可能已经有所发展或是发生改变。

    用到一个库,,它有一个接口函数如下:

    /**
     * @brief     interface print format data
     * @param[in] fmt is the format data
     * @note      none
     */
    void ov2640_interface_debug_print(const char *const fmt, ...)
    {
    }
    

    这个函数的函数原型与 printf 完全一致,,所以我想像下面这样直接把它的参数传递给 printf ,,可是编译器报错,,请问应该怎么改??

    void ov2640_interface_debug_print(const char *const fmt, ...)
    {
    	printf(fmt, ...);
    }
    
    11 条回复    2024-11-13 10:29:50 +08:00
    654656413245
        1
    654656413245  
       2024-11-12 17:52:45 +08:00
    printf(fmt, __VA_ARGS__);
    geelaw
        2
    geelaw  
       2024-11-12 17:58:21 +08:00 via iPhone   ❤️ 2
    关键词:vprintf
    XIVN1987
        3
    XIVN1987  
    OP
       2024-11-12 18:43:58 +08:00
    @geelaw
    下面这样确实可以,,不过感觉还是不够简洁、直接。。
    ``` C
    void ov2640_interface_debug_print(const char *const fmt, ...)
    {
    va_list args;

    va_start(args, fmt);
    vprintf(fmt, args);
    va_end(args);
    }
    ```
    wfg
        4
    wfg  
       2024-11-12 19:14:42 +08:00 via iPhone
    @XIVN1987 C 不是一門簡潔、直接的語言
    julyclyde
        5
    julyclyde  
       2024-11-12 19:19:01 +08:00   ❤️ 1
    @XIVN1987 这就是标准做法
    geelaw
        6
    geelaw  
       2024-11-12 19:41:21 +08:00
    @XIVN1987 #3 好像可变参数本身就不是简洁直接的东西。

    另外这也提示你应该把实现放在 void v_ov2460_interface_debug_print(char const *fmt, va_list arg); 里面,并在可变参数版本里调用它。

    请注意,如果这个函数本身需要在 vprintf 之外操作可变参数列表,需要 va_copy 之,否则行为不确定。
    pursuer
        7
    pursuer  
       2024-11-12 22:00:15 +08:00
    我觉得 C 中缺少两个机制,一个是动态函数调用,类似 libffi 。另一个是简单的栈切换,类似 ucontext 。这两个东西依赖 C 的 ABI ,又有不少上层应用需要这个特性,特别是 ffi 。不知道会不会有一天被加入标准库。
    cwxiaos
        8
    cwxiaos  
       2024-11-12 22:10:29 +08:00 via iPhone
    用宏套一下也可以吧
    XIVN1987
        9
    XIVN1987  
    OP
       2024-11-13 09:02:27 +08:00
    感谢大家回复,,

    那看来 vprintf 就是最简单的了,,感谢 @geelaw 指点。。
    codehz
        10
    codehz  
       2024-11-13 10:29:10 +08:00
    其实要用编译器扩展的话可以简单点,直接
    void ov2640_interface_debug_print(const char *const fmt, ...)
    {
    printf(fmt, __builtin_va_arg_pack());
    }
    (仅限于 gcc ,嵌入式的话可以不考虑别的编译器
    不过还是不建议这么写
    codehz
        11
    codehz  
       2024-11-13 10:29:50 +08:00
    哦忘了,那玩意得加__attribute__ ((__always_inline__))才可以,不内联的情况下会失败
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   860 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 18:55 · PVG 02:55 · LAX 10:55 · JFK 13:55
    ♥ Do have faith in what you're doing.