C 预处理器宏和自定义可变参数函数的警告抑制?

问题描述 投票:0回答:1

我正在尝试创建一类可以使用任意数量和任何类型的参数调用的函数 - 类似于

printf
,但有一个关键区别:我想在传递所有参数之前将它们转换为
uint64_t
到函数。理想情况下,这应该是隐式的,即我不必每次都写
( uint64_t ) arg1 , ( uint64_t ) arg2 ,  ( uint64_t ) arg3 , . . .

我当前的解决方案基于对this上一个问题的回答。

这是对任何非指针类型执行我想要的操作的基本方法:

// The variadic function.
void _f ( char c , uint64_t arg_count , uint64_t* args );

// Macro to append two extra arguments comprising the variadic argument list to the function.
#define ARGS(...) \
    sizeof ( ( uint64_t[] ){ __VA_ARGS__ } ) / sizeof ( uint64_t ) \
  , ( uint64_t[] ){ __VA_ARGS__ }

// Macro to call the variadic function.
#define f(c,...) \
    _f ( (c) , ARGS ( __VA_ARGS__ ) )

可以这样使用:

f ( 'A' , 27 , -30L , '/' );

我也希望能够将指针传递给函数,但这会引发编译器警告

-Wint-conversion
,因此我必须添加一些从this问题的答案中得到的额外宏,以在每次调用函数时抑制警告使用
ARGS
的称为:

#define PRAGMA(args) \
    _Pragma ( #args )

#define DISABLE_WARNING(warning)   \
    PRAGMA ( GCC diagnostic push ) \
    PRAGMA ( GCC diagnostic ignored #warning )

#define REENABLE_WARNING() \
    PRAGMA ( GCC diagnostic pop )

// New macro to call the variadic function.
#define f(c,...) \
({ \
    DISABLE_WARNING ( -Wint-conversion ) \
    _f ( (c) , ARGS ( __VA_ARGS__ ) ); \
    REENABLE_WARNING () \
})

现在该函数也可以这样调用:

float f_ = 32.2f;
f ( 'A' , 27 , -30L , '/' , &f_ , &"Hello world" );

但是,由于语法限制,

#pragma
无法嵌入表达式中,因此该函数无法返回值。当然,我可以让函数有一个额外的指针参数并为其写入一个返回值,但理想情况下我希望函数本身直接返回一个
uint64_t
。有办法做到这一点吗?

c gcc clang c-preprocessor variadic-functions
1个回答
0
投票

不要使用表达式语句语法(它是编译器扩展),而是使用

do..while(0)
循环。

#define f(c,...) \
do { \
    DISABLE_WARNING ( -Wint-conversion ) \
    _f ( (c) , ARGS ( __VA_ARGS__ ) ); \
    REENABLE_WARNING () \
} while(0)
© www.soinside.com 2019 - 2024. All rights reserved.