一句话概括:使用va_list
, va_start
, va_end
的函数无法强制内联,即具有类似如下原型的函数无法被标记为inline __attribute__((always_inline))
或__forceinline
(除非你不用参数的变长部分,那也就没必要这样定义)。
void f(char* fmt, ...);
从底层来看,inline的原理是编译时展开,如果允许调用va_xx
的函数被内联,那么获取到的将是展开位置的变长参数列表(而且va_start
和va_end
事实上是宏而非函数),可能不符合预期行为。
...
) 的 获取机制 是基于底层 ABI 的。va_start()
、va_arg()
、va_end()
都依赖当前调用帧(调用栈上的位置、寄存器布局)。一旦你试图内联这样的函数:
因此,编译器通常明确禁止将带 ...
的函数(或调用 va_start
的函数)标记为 inline
或__forceinline
。
利用snprintf()
格式化字符数组,如下:
inline __attribute__((always_inline)) void f(const char* content){
printf(content, NULL);
}
int main(){
char content[20];
snprintf(content, 20, "Value = %d", 42);
f(content);
}
该方案的优势在于通用性强,未涉及任何“新”特性,最纯粹的C方案。
...
(代码如下:
#include <tuple>
#include <cstdio>
template <typename... Args>
inline __attribute__((always_inline)) void sub_log(const char* format, Args&&... args) {
std::printf(format, args...);
}
template <typename... Args>
inline __attribute__((always_inline)) void log(const char* format, Args&&... args) {
sub_log(format, args...);
}
int main() {
log("%s %d\n", "The number is", 42);
return 0;
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。