strlen 是否针对字符串文字进行了优化?
Is strlen Optimized out for String Literals?
所以说我有这个:
const auto foo = "lorem ipsum"
如果我在我的代码中使用 strlen(foo)
,11 是在 运行 时找到的还是在编译时注入的?
这完全取决于您的编译器以及您是否在启用优化的情况下构建。
一个好的现代编译器可能会优化 strlen
并在优化时产生 11 作为常量,但语言中没有任何强制它这样做。所以编译器生成函数调用也是完全有效的。
您只需在您选择的优化级别使用您选择的编译器进行测试,然后读取生成的程序集。
答案取决于编译器和当前的优化级别。
此 C++ 代码的快速实验
#include <cstring>
int strlen_of_const() {
return strlen("lorem ipsum");
}
on compiler explorer 显示,一些编译器会优化调用,而其他编译器会在运行时进行调用。例如,gcc 优化了调用:
strlen_of_const():
mov eax, 11
ret
另一方面,MSVC 保持调用:
$SG3533 DB 'lorem ipsum', 00H
EXTRN strlen:PROC
strlen_of_const PROC
sub rsp, 40 ; 00000028H
lea rcx, OFFSET FLAT:$SG3533
call strlen
add rsp, 40 ; 00000028H
ret 0
strlen_of_const ENDP
标准不允许实现添加 constexpr,除非明确要求:
[constexpr.functions]
This document explicitly requires that certain standard library functions are constexpr ([dcl.constexpr]).
An implementation shall not declare any standard library function signature as constexpr except for those where it is explicitly required.
所以strlen
超出范围。
但是,为了支持 string_view
的 constexpr
构造函数,C++17 标准要求 char_traits
的某些成员,如 char_traits::length
,无论如何都是 constexpr。
本月我们发布了 gcc 8.1 and MSVC 15.7 的新编译器版本,因此主要编译器的最新版本现在都将 char_traits::length
实现为 constexpr。
所以说我有这个:
const auto foo = "lorem ipsum"
如果我在我的代码中使用 strlen(foo)
,11 是在 运行 时找到的还是在编译时注入的?
这完全取决于您的编译器以及您是否在启用优化的情况下构建。
一个好的现代编译器可能会优化 strlen
并在优化时产生 11 作为常量,但语言中没有任何强制它这样做。所以编译器生成函数调用也是完全有效的。
您只需在您选择的优化级别使用您选择的编译器进行测试,然后读取生成的程序集。
答案取决于编译器和当前的优化级别。
此 C++ 代码的快速实验
#include <cstring>
int strlen_of_const() {
return strlen("lorem ipsum");
}
on compiler explorer 显示,一些编译器会优化调用,而其他编译器会在运行时进行调用。例如,gcc 优化了调用:
strlen_of_const():
mov eax, 11
ret
另一方面,MSVC 保持调用:
$SG3533 DB 'lorem ipsum', 00H
EXTRN strlen:PROC
strlen_of_const PROC
sub rsp, 40 ; 00000028H
lea rcx, OFFSET FLAT:$SG3533
call strlen
add rsp, 40 ; 00000028H
ret 0
strlen_of_const ENDP
标准不允许实现添加 constexpr,除非明确要求:
[constexpr.functions]
This document explicitly requires that certain standard library functions are constexpr ([dcl.constexpr]). An implementation shall not declare any standard library function signature as constexpr except for those where it is explicitly required.
所以strlen
超出范围。
但是,为了支持 string_view
的 constexpr
构造函数,C++17 标准要求 char_traits
的某些成员,如 char_traits::length
,无论如何都是 constexpr。
本月我们发布了 gcc 8.1 and MSVC 15.7 的新编译器版本,因此主要编译器的最新版本现在都将 char_traits::length
实现为 constexpr。