
一句话概括:使用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 删除。