我正在try 创建一个函数类,它可以使用任何数量和任何类型的参数调用--类似于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
,因此我不得不添加一些额外的宏来 suppress 每次调用使用ARGS
的函数时的警告,这些宏来自对this的回答:
#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
.有办法做到这一点吗?