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_viewconstexpr 构造函数,C++17 标准要求 char_traits 的某些成员,如 char_traits::length,无论如何都是 constexpr。

本月我们发布了 gcc 8.1 and MSVC 15.7 的新编译器版本,因此主要编译器的最新版本现在都将 char_traits::length 实现为 constexpr。