将 libfmt 与旧版一起使用 API

Using libfmt with a legacy API

我想在遗留 C API 之上针对现代格式化库(特别是 libfmt)衡量 vsnprintf 的性能。不可能直接在调用者处使用 C++。我该怎么做?

const char *fmt, ...

我们传递的参数出乎意料地是格式字符串后跟可变参数列表。输出需要以零终止。如果这不可能获得最大性能,我将不得不手动实例化每个格式字符串的版本。现在我正在努力避免这种情况。

目的地是一个具有规定最大长度的缓冲区。我们不能将堆用于任何事情。没有堆。

{fmt} 是一个 C++ 库,它不提供 C API,因此您需要使用 C++ 编译器或编写您自己的 C 包装器。您可以使用 dynamic_format_arg_store 在包装器中构建参数列表,但它的效率低于直接使用 C++ API。

与 printf 相比,fmt 的工作方式有一个非常根本的区别。即,fmt 的格式化字符串不包含类型信息。

fmt 基于 C++ 可变参数模板。预计类型信息将按照 C++ 的典型方式传输:通过 compile-time 机制。因此,fmt 的格式字符串不需要重复所有格式化函数固有包含的类型信息。这种强类型允许 fmt 允许 type-based 扩展功能。

C 可变参数擦除所有类型信息。如果字符串中没有存储类型信息,就无法恢复 fmt 需要 来完成其工作的类型信息。

libfmt 库包含一个 dynamic_format_arg_store 类型(这不是 C++20 的一部分,但我认为您可以构建它)。但是,即使这样也需要您知道 存储参数时的类型。因为 C 可变参数已经删除了类型,所以你是 out-of-luck.

fmt 作为库的基本假设使其与 C 可变参数不兼容。