什么是 strlen 省略?
What is strlen elision?
我可以 see it listed 作为现代 C++ 习语之一,但它到底是什么?
只是copy elision的一种吗?
恕我直言,self-evident 在我看来,如果编译器理解 strlen 的语义,并且在编译时知道所讨论的字符串,那么编译器就可以发出一个常量而不是在运行时评估字符串的长度(通过任何方式)。这就是这里发生的一切。相信 Microsoft 的营销部门 hype-up 如此简单的功能。
我 对这一切感兴趣的是(优化)编译器越来越倾向于将常用的运行时库函数视为内在函数,并尽可能为它们生成更好的代码。这已经持续了一段时间——memcpy 和 memset 是明显的例子——但我最近在 Godbolt 的编译器资源管理器中玩耍,很惊讶地看到 gcc 取代了它:
printf (" ");
有了这个:
putchar (' ');
震惊?我也是,我不确定我是否喜欢它。我可能有一个自定义的 printf 来做一些特别的事情,这种诡计会让人大吃一惊。在我看来,这么小的收益冒着很大的风险(编译器作者)。
您可能知道 std::strlen
遍历整个字符串。在某些情况下,这可能效率低下,因为这意味着 CPU 必须开始计算字符,这会减少其他内容的缓存位置。
但在大多数情况下,编译器能够优化 std::strlen
并计算字符串本身的字符数,而不是让生成的程序这样做。这有时称为 strlen 省略(因为它省略了对 strlen 的调用)。
std::strlen
的 simple example 会完全优化。
#include <cstring>
int main() {
return std::strlen("hi");
}
在 -O3
下生成的程序集是
main: # @main
mov eax, 2
ret
连under -O0
都没有产生循环!
现在这是一个相当简单的示例,但它甚至可以用于 std::strlen
.
的更复杂的用法
#include <cstring>
int main(int argc, char**) {
const char *string;
if (argc == 1)
string = "hello";
else if (argc == 2)
string = "world";
else if (argc == 3)
string = "!";
return std::strlen(string);
}
这里的字符串完全optimized away,还有std::strlen
调用
我可以 see it listed 作为现代 C++ 习语之一,但它到底是什么?
只是copy elision的一种吗?
恕我直言,self-evident 在我看来,如果编译器理解 strlen 的语义,并且在编译时知道所讨论的字符串,那么编译器就可以发出一个常量而不是在运行时评估字符串的长度(通过任何方式)。这就是这里发生的一切。相信 Microsoft 的营销部门 hype-up 如此简单的功能。
我 对这一切感兴趣的是(优化)编译器越来越倾向于将常用的运行时库函数视为内在函数,并尽可能为它们生成更好的代码。这已经持续了一段时间——memcpy 和 memset 是明显的例子——但我最近在 Godbolt 的编译器资源管理器中玩耍,很惊讶地看到 gcc 取代了它:
printf (" ");
有了这个:
putchar (' ');
震惊?我也是,我不确定我是否喜欢它。我可能有一个自定义的 printf 来做一些特别的事情,这种诡计会让人大吃一惊。在我看来,这么小的收益冒着很大的风险(编译器作者)。
您可能知道 std::strlen
遍历整个字符串。在某些情况下,这可能效率低下,因为这意味着 CPU 必须开始计算字符,这会减少其他内容的缓存位置。
但在大多数情况下,编译器能够优化 std::strlen
并计算字符串本身的字符数,而不是让生成的程序这样做。这有时称为 strlen 省略(因为它省略了对 strlen 的调用)。
std::strlen
的 simple example 会完全优化。
#include <cstring>
int main() {
return std::strlen("hi");
}
在 -O3
下生成的程序集是
main: # @main
mov eax, 2
ret
连under -O0
都没有产生循环!
现在这是一个相当简单的示例,但它甚至可以用于 std::strlen
.
#include <cstring>
int main(int argc, char**) {
const char *string;
if (argc == 1)
string = "hello";
else if (argc == 2)
string = "world";
else if (argc == 3)
string = "!";
return std::strlen(string);
}
这里的字符串完全optimized away,还有std::strlen
调用