在不生成汇编代码进行检查的情况下,对格式字符串进行编译时格式检查?

huangapple go评论63阅读模式
英文:

fmt compile time format string check without generating asm code for the check?

问题

The user provided a code-related question with multiple parts. Here's the translated response for the relevant part:

在不生成任何汇编代码(最终不会被编译进去)的情况下,是否有办法要求 fmt 库对格式字符串与参数类型进行编译时检查?

对于示例,可以看到以下代码:

#include <fmt/core.h>
#include <fmt/compile.h>

int main() {
    fmt::format(FMT_STRING("{:d}"), 123);
}

上面的代码会进行检查(如果编译器支持 constvalFMT_STRING 是可选的),但它也会生成一些汇编代码,你可以在链接中看到。

我正在寻找一种方法,在编译时触发检查,而不会在最终的二进制文件中生成任何汇编代码。原因是我想创建自己的记录器(在 fmt 之上)(类似于这个),但我想推迟实际的格式化到另一个线程,只在编译时执行检查(没有任何汇编代码)。这是否可能?

英文:

Is there anyway to ask fmt library to do compile time check on the format string against the argument types without generating any asm code (to be compiled out)?

For example,

#include &lt;fmt/core.h&gt;
#include &lt;fmt/compile.h&gt;

int main() {
	fmt::format(FMT_STRING(&quot;{:d}&quot;), 123);
}

Code above does the check (FMT_STRING is optional for compiler supporting constval) but it also generates some asm code as you can see in the link.

I am looking for a way to trigger the check at compile time without any asm in the final binary. The reason is that I would like to create my own logger (on top of fmt) (similar idea to this) but I would like to defer the actual formatting to another thread later but only have the compile time check done (without any asm code). Is it possible?

答案1

得分: 3

使用 static_assert 检查 formatted_size 的返回值与 FMT_COMPILE 宏。

英文:

Use static_assert to check the return value of formatted_size with FMT_COMPILE macro

static_assert(fmt::formatted_size(FMT_COMPILE(&quot;{:d}&quot;), 123));

Demo

答案2

得分: 1

以下是翻译好的部分:

你可以按以下方式检查格式字符串:

#include <fmt/core.h>

int main() {
  constexpr auto s = fmt::format_string<int>("{:d}");
}

这没有运行时效果,如你可以从生成的汇编中看到 (https://godbolt.org/z/Eqxa1hf5T):

main:
        mov     eax, 0
        ret

通常情况下,format_string 用作函数参数,因此在调用函数时会自动执行检查,例如:

template <typename... Args>
void log(fmt::format_string<Args...> fmt, Args&&... args) {
  // 在这一点上,格式字符串已经经过检查。
  // 进行日志记录。
}

FMT_STRING 是一种用于进行编译时检查的传统机制,我不建议使用它。

我也不建议使用 FMT_COMPILE 进行检查,因为并不是所有的格式化器都能在编译时工作,并且它的效率较低,因为需要进行不必要的大小计算。

英文:

You can check the format string as follows:

#include &lt;fmt/core.h&gt;

int main() {
  constexpr auto s = fmt::format_string&lt;int&gt;(&quot;{:d}&quot;);
}

This has no runtime effect as you can see from the generated assembly (https://godbolt.org/z/Eqxa1hf5T):

main:
        mov     eax, 0
        ret

Normally format_string is used as a function argument so that the check is done automatically when the function is called, e.g.

template &lt;typename... Args&gt;
void log(fmt::format_string&lt;Args...&gt; fmt, Args&amp;&amp;... args) {
  // Format string has already been checked at this point.
  // Do the logging.
}

FMT_STRING is a legacy mechanism to do the compile-time checks and I wouldn't recommend using it.

I wouldn't recommend using FMT_COMPILE for checks either because not all formatters work at compile time and is less efficient because it needs to do unnecessary size computation.

huangapple
  • 本文由 发表于 2023年5月25日 15:36:16
  • 转载请务必保留本文链接:https://go.coder-hub.com/76329898.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定