【问题标题】:Is strlen Optimized out for String Literals?strlen 是否针对字符串文字进行了优化?
【发布时间】:2019-04-28 05:23:01
【问题描述】:

所以说我有这个:

const auto foo = "lorem ipsum"

如果我在我的代码中使用strlen(foo),11 是在运行时找到的还是在编译时注入的?

【问题讨论】:

标签: c++ c-strings string-length string-literals compile-time-constant


【解决方案1】:

答案取决于编译器和当前的优化级别。

对这段 C++ 代码的快速实验

#include <cstring>
int strlen_of_const() {
    return strlen("lorem ipsum");
}

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 size_t strlen(const char*) 函数重载来保证这会发生。因此,我不能依赖这种情况。
【解决方案2】:

这完全取决于您的编译器以及您是否在构建时启用了优化。

一个好的现代编译器可能会优化 strlen 并在优化时生成 11 作为常量,但语言中没有任何东西强制它这样做。所以编译器生成函数调用也是完全有效的。

您只需在您选择的优化级别使用您选择的编译器进行测试并读取生成的程序集。

【讨论】:

    【解决方案3】:

    该标准不允许实现添加 constexpr,除非明确要求:

    [constexpr.functions]
    本文档明确要求某些标准库函数是 constexpr ([dcl.constexpr])。 除非明确要求,否则实现不应将任何标准库函数签名声明为 constexpr。

    所以strlen 越界了。

    但是,为了支持 string_viewconstexpr 构造函数,C++17 标准要求 char_traits 的某些成员,例如 char_traits::length,无论如何都是 constexpr。

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

    【讨论】:

      猜你喜欢
      • 2012-01-13
      • 1970-01-01
      • 2011-05-16
      • 2012-07-06
      • 2010-09-22
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多